首页 > 编程语言 >C/C++可变参数函数

C/C++可变参数函数

时间:2024-01-22 23:11:07浏览次数:31  
标签:va 函数 int void list C++ ap 参数 可变

C 可变参数

typedef char* va_list;
void va_start ( va_list ap, prev_param );
type va_arg ( va_list ap, type ); 
void va_end ( va_list ap );


// 32位机器对int大小向上取整,64位机器对int64大小向上取整,因为参数在栈中传递都要对齐
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )

#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )

#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

#define va_end(ap) ( ap = (va_list)0 ) 

一个简单的例子

#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
void funcarg(int n, ...){
    int t;
    va_list arg;
    va_start(arg, n);
    for(int i=0;i<n;i++){
        t = va_arg(arg, int);
        printf("%d ",t);
    } 
    va_end(arg);
}
int main()
{
    funcarg(3,1,2,3);
}

缺点:无法判断参数类型,只能用事先约定好的类型来取值,如果取值类型不对,会出现未知错误。

C++ initializer_list

使用initializer_list可以传递任意多个同类型的参数,类似于vector,是一种模板容器,可以将多个同类型参数打包成一个参数对象,然后传递给函数。

void funcinitial(initializer_list<int> ls){
    for(auto x:ls) cout<<x<<" ";
}

缺点:只支持单一类型,只读不写。

C++ 可变参数模板

接受可变参数的模板函数,可变参数称为参数包,包括模板参数包和函数参数包。
编译器从实参推断模板参数类型,并推断参数数目,然后实例化不同版本。
注意需要另外定义非可变参数的版本,负责终止递归。

template<typename T>
void funcvartemplate(T t){
    cout<<t<<" ";
}
template<typename T,typename ... Args>
void funcvartemplate(T t, Args ... args){  // 扩展Args
    cout<<t<<" ";
    funcvartemplate(args...);              // 扩展args
}

包扩展,就是将包分解为构成元素,对每个元素应用模式,获得扩展后的列表。
对于上面的例子,第一个扩展操作为扩展模板参数包,为print生成函数参数列表,第二个扩展在对print的调用中,为print生成实参列表。

标签:va,函数,int,void,list,C++,ap,参数,可变
From: https://www.cnblogs.com/wangerblog/p/17981342

相关文章

  • C++类和对象-对象特性(2)
    一.构造函数的分类及调用两种分类方式:按参数分为:有参构造和无参构造按类型分为:普通构造和拷贝构造三种调用方式:括号法显示法隐式转换法二.拷贝构造函数调用时机拷贝构造函数调用时机C++中拷贝构造函数调用时机三种情况使用一个已经创建完毕的对象来初始化一个新......
  • 第十二天:函数 function
    一、函数介绍函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分函数和shell程序区别Shell程序在子Shell中运行函数在当前Shell中运行。因此在当前Shell中,函......
  • [office] excel排名函数使用教程
    Excel中经常需要使用到排名函数对数据表进行排名,排名函数具体该如何使用呢?下面是小编带来的关于excel排名函数使用教程,希望阅读过后对你有所启发!excel排名函数使用教程:排名函数使用步骤1:不管在学校还是各个统计领域,排名应用随处可见,如果排序会打乱原有次序,那么好多朋......
  • C++学习笔记
    C++学习笔记(1)预编译、编译、链接预编译(Preprocessing)cppreference中:GPT这么说:C++预编译是指在编译阶段之前对代码进行的一系列预处理操作。预编译的目的是为了将代码中的预处理指令和宏展开,以及进行一些其他的预处理操作。预处理指令包括以井号(#)开头的指令,如#include、#......
  • C++日志记录库spdlog
    镜像库https://gitee.com/yctxkj/spdlog.gitspdlog是基于C++11实现的一款纯头文件的日志管理库(git地址:https://github.com/gabime/spdlog,API说明:https://spdlog.docsforge.com/v1.x/1.quickstart/):配置特别简单,仅包含头文件即可;写日志方式简单明了;可实现自动按日期创建日志文......
  • KY85 二叉树C++
    递归判断当前节点和n的关系就好了。如果小于等于n那就是存在。#include<iostream>usingnamespacestd;intcount(inti,intn){if(i>n)return0;returncount(2*i,n)+count(2*i+1,n)+1;}intmain(){intn,m;while(cin>>m>>n){if(n==0)......
  • 【C++入门到精通】C++入门 —— 类和对象(拷贝构造函数、赋值运算符重载、const成员函
    编辑一、前言二、拷贝构造函数⭕拷贝构造函数概念⭕拷贝构造函数的特点⭕拷贝构造函数的几种类型三、赋值运算符重载⭕运算符重载概念⭕赋值运算符重载⭕前置++和后置++重载四、const成员函数⭕const成员函数概念⭕常量成员函数需要满足的特点⭕常量成员函数有利条件⭕const常量的......
  • 【C++进阶】function和bind及可变模板参数
     文章目录1.function和bind1.1function使用方法1.2bind2.可变模板参数2.1可变模板参数函数2.2可变模板参数的展开 1.function和bindC++中的function和bind是为了更方便地进行函数对象的封装和调用而设计的。function是一个通用的函数对象容器......
  • 【C++入门到精通】C++入门 —— 类和对象(初始化列表、Static成员、友元、内部类、匿名
     目录一、初始化列表⭕初始化列表概念⭕初始化列表的优点⭕使用场景⭕explicit关键字二、Static成员⭕Static成员概念......
  • 4147:汉诺塔问题(Tower of Hanoi)C++
    递归C和C++一样,就写个C++了。#include<iostream>usingnamespacestd;voidmove(intn,chara,charb,charc){if(n<=0)return;move(n-1,a,c,b);cout<<n<<":"<<a<<"->"<<c<<'\n�......