va_start() 和va_end() 函数说明_songguozhi的博客-程序员秘密

技术标签: iostream  system  null  list  fun  数据结构  

1:当无法列出传递函数的所有实参的类型和数目时,可用省略号指定参数表
void foo(...);
void foo(parm_list,...);

2:函数参数的传递原理
函数参数是以数据结构:栈的形式存取,从右至左入栈.eg:
#include <iostream>
void fun(int a, ...)
{
int *temp = &a;
temp++;
for (int i = 0; i < a; ++i)
{
cout << *temp << endl;
temp++;
}
}

int main()
{
int a = 1;
int b = 2;
int c = 3;
int d = 4;
fun(4, a, b, c, d);
system("pause");
return 0;
}
Output::
1
2
3
4

3:获取省略号指定的参数
在函数体中声明一个va_list,然后用va_start函数来获取参数列表中的参数,使用完毕后调用va_end()结束。像这段代码:
void TestFun(char* pszDest, int DestLen, const char* pszFormat, ...)
{
va_list args;
va_start(args, pszFormat);
_vsnprintf(pszDest, DestLen, pszFormat, args);
va_end(args);
}

4.va_start使argp指向第一个可选参数。va_arg返回参数列表中的当前参数并使argp指向参数列表中的下一个参数。va_end把argp指针清为NULL。函数体内可以多次遍历这些参数,但是都必须以va_start开始,并以va_end结尾。

  1).演示如何使用参数个数可变的函数,采用ANSI标准形式
#include 〈stdio.h〉
#include 〈string.h〉
#include 〈stdarg.h〉
/*函数原型声明,至少需要一个确定的参数,注意括号内的省略号*/
int demo( char, ... );
void main( void )
{
    demo("DEMO", "This", "is", "a", "demo!", "");
}
/*ANSI标准形式的声明方式,括号内的省略号表示可选参数*/
int demo( char msg, ... )
{
        /*定义保存函数参数的结构*/
    va_list argp;
    int argno = 0;
    char para;

      /*argp指向传入的第一个可选参数,msg是最后一个确定的参数*/
   va_start( argp, msg );
    while (1)
        {
     para = va_arg( argp, char);
        if ( strcmp( para, "") == 0 )
        break;
        printf("Parameter #%d is: %s/n", argno, para);
        argno++;
   }
   va_end( argp );
   /*将argp置为NULL*/
return 0;
}

2)//示例代码1:可变参数函数的使用
#include "stdio.h"
#include "stdarg.h"
void simple_va_fun(int start, ...)
{
     va_list arg_ptr;
    int nArgValue =start;
     int nArgCout=0;      //可变参数的数目
    va_start(arg_ptr,start); //以固定参数的地址为起点确定变参的内存起始地址。
     do
     {++nArgCout;
         printf("the %d th arg: %d/n",nArgCout,nArgValue);      //输出各参数的值
         nArgValue = va_arg(arg_ptr,int);                       //得到下一个可变参数的值
     } while(nArgValue != -1);               
     return;
}
int main(int argc, char* argv[])
{
     simple_va_fun(100,-1);
     simple_va_fun(100,200,-1);
     return 0;
}


3)//示例代码2:扩展——自己实现简单的可变参数的函数。
下面是一个简单的printf函数的实现,参考了<The C Programming Language>中的例子
#include "stdio.h"
#include "stdlib.h"
void myprintf(char* fmt, ...)         //一个简单的类似于printf的实现,//参数必须都是int 类型
{
     char* pArg=NULL;                //等价于原来的va_list
     char c;
   
     pArg = (char*) &fmt;           //注意不要写成p = fmt !!因为这里要对//参数取址,而不是取值
     pArg += sizeof(fmt);          //等价于原来的va_start         

     do
     {
         c =*fmt;
         if (c != '%')
         {
             putchar(c);             //照原样输出字符
         }
         else
         {
            //按格式字符输出数据
            switch(*++fmt)
            {
             case'd':
                 printf("%d",*((int*)pArg));             break;
             case'x':
                 printf("%#x",*((int*)pArg));
                 break;
             default:
                 break;
             }
             pArg += sizeof(int);                //等价于原来的va_arg
         }
         ++fmt;
     }while (*fmt != '/0');
     pArg = NULL;                                //等价于va_end
     return;
}
int main(int argc, char* argv[])
{
     int i = 1234;
     int j = 5678;
   
     myprintf("the first test:i=%d/n",i,j);
     myprintf("the secend test:i=%d; %x;j=%d;/n",i,0xabcd,j);
     system("pause");
     return 0;
}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/songguozhi/article/details/3117673

智能推荐

车牌自动识别在智能交通系统中的应用及前景分析_uuZC66688的博客-程序员秘密

系统主要由前端数据采集子系统、网络传输子系统、中心管理子系统等部分组成。前端数据采集子系统通过视频跟踪和分析技术获取车辆的经过时间、速度、图片、车牌号码、车身颜色等数据。数据通过网络传输子系统传输到中心管理子系统。中心管理子系统对数据进行集中管理、存储、共享等处理。

虚拟机无法上网问题——一切都正常时,本地服务VMwareDHCP、VMwareNAT启动没?_麻匪的博客-程序员秘密

虚拟机无法上网问题——一切都正常时,本地服务VMwareDHCP、VMwareNAT启动没?1、在网上找了一大堆资料,开始逐项检查:NAT模式配置正确;network.service正常,/etc/sysconfig/network-scripts/ifcfg-ens*配置正常;在设置中添加适配器默认地址;检查MAC地址是否一致;在配置文件中,添加“HWADDR=“∗∗.∗∗...

Bzoj4568: [Scoi2016]幸运数字_weixin_30448603的博客-程序员秘密

Bzoj4568: [Scoi2016]幸运数字线性基+倍增+LCA原来线性基还能这么考……一开始看到这个题以为是树上差分线性基,然而线性基不支持删除,所以就挂了。后来想到倍增线性基,其实到这里思路就很清晰了。倍增线性基,A[i][j]表示从i开始向上2j步的线性基,询问时暴力合并即可。 1 xxj hb(xxj a,xxj b) 2 { 3 xxj ans...

HttpClient三种不同的服务器认证客户端方案_Only鱼籽酱的博客-程序员秘密

HttpClient三种不同的认证方案: Basic, Digest and NTLM. 这些方案可用于服务器或代理对客户端的认证,简称服务器认证或代理认证。服务器认证  HttpClient处理服务器认证几乎是透明的,仅需要开发人员提供登录信息(login credentials)。登录信息保存在HttpState类的实例中,可以通过 setCredentials(String

Android常用对话框_android系统提示对话框_xivierID的博客-程序员秘密

学习目标:两周入门Android学习内容:常见对话框:对话框是程序与用户交互的一种方式,通常用于显示当前程序提示信息以及相关说明,以小窗口形式展现普通对话框:通过AlertDialog.Builder(this).create来创建对话框最后通过 .show()来显示对话框,设置确定和取消的第二个参数为是否设置监听,没有则填”null”这里的调用方式使用的是链式调用,因为每次的返回值都是本身也就是Builder其中this的意思是当前对象,因为Dialog在Activity中on

【转】如何撤销git reset --hard操作_git reset 撤销_Qidi_Huang的博客-程序员秘密

【版权声明】    原文链接为《找回Git中丢失的Commit》【正文】    在使用Git的过程中,有时候会因为一些误操作,比如reset、rebase、merge等。特别是在Commit之后又执行了git reset --hard HEAD强制回滚本地记录以及文件到服务器版本,导致本地做的修改全部恢复到Git当前分支的服务器版本,同时自己的Commmit记录也消失了。碰

随便推点

哈希(Hash) - 开散列/闭散列_风&646的博客-程序员秘密

哈希的基本认识,哈希函数的设计,以及开散列和闭散列的实现

写在冬日的第一天--一个女程序员第九年工作总结(及杂七杂八)_clear_zero的博客-程序员秘密

又到一年写总结的时候了。今年比较特殊,因为大部分时间在休产假。所以今年会在有限的工作总结后面写一些杂七杂八。其实去年写总结的时候已经到了孕晚期,我属于比较晚才歇的人。确切地说我的产假开始于生产前一天,除了那种从岗位直接到产房的人我算是相当晚的了。肚子比较给力没有大到让我开不了车的程度,于是就一直上班,总比在家无聊要好。还是那句话,我在小地方,小单位,属于随波逐流不求上进型。这些

python编写文件管理系统_Python使用文件操作实现一个XX信息管理系统的示例_weixin_39631755的博客-程序员秘密

写在前面大家好,我是第一次python学了一个学期,期末要完成一个毕业生信息管理系统大作业的小韩了,由于上次没有仔细看开发实现的要求,实现了一个简单的毕业生信息管理系统,而这次专门整理了两种使用文件进行保存数据实现的毕业生信息管理系统,因为是第一次学python,还不太熟悉python的写法, 而之前是学 c 、c++,感觉我的这个写的有一股 c/c++的内味:1. 使用excel .xlsx 保...

Bootstrap4让两个input并排显示_两个input并列_忘尘~的博客-程序员秘密

1、使用.row和.col组合&lt;form&gt; &lt;div class="row"&gt; &lt;div class="col"&gt; &lt;input type="text" class="form-control" placeholder="First name"&gt; &lt;/div&gt; &lt;div class="c...

mysql (一)数据库+数据库管理系统+SQL三者之间的关系 +++SQL语句的整体分类_数据库和sql和数据库管理系统他们之间的关系_weixin_74的博客-程序员秘密

什么是数据库?什么是数据库管理系统?什么是SQL?他们之间的关系是什么?数据库: 英文单词DataBase,简称DB。按照一定格式存储数据的一些文件的组合。 顾名思义:存储数据的仓库,实际上就是一堆文件。这些文件中存储了 具有特定格式的数据。数据库管理系统: DataBaseManagement,简称DBMS。 数据库管理系统是专门用来管理数据库中数据的,数据库管理系统可以 对数据库当中的数据进行增删改查。 常见的数据库管理系统:

PTA-Python-第4章-5 求e的近似值 (15分)_邂逅模拟卷的博客-程序员秘密

点击链接PTA-Python-AC全解汇总题目:自然常数 e 可以用级数 1+1/1!+1/2!+⋯+1/n!+⋯ 来近似计算。本题要求对给定的非负整数 n,求该级数的前 n+1 项和。输入格式:输入第一行中给出非负整数 n(≤1000)。输出格式:在一行中输出部分和的值,保留小数点后八位。输入样例:10输出样例:2.71828180我的代码:import math n=int(input())print("%.8f"%(sum(1/math.factorial(x) for x

推荐文章

热门文章

相关标签