zoukankan      html  css  js  c++  java
  • 可变参数使用

    在C中,可变参数用于参数个数,类型不确定的情况,如printf,snprintf函数的实现。

    当我们无法列出传递函数的所有实参的类型和数目时,可以用省略号指定参数表

    void func(...);
    void func(parm_list,...);
    

    这是C传参的一种形式,与固定参数不同。

    函数参数的传递原理

    函数参数以栈的形式存储,从右往左入栈。
    举个例子:

    void func(int x, float y, char z);
    

    在调用函数的时候,实参z先入栈,然后是y,最后是x。在内存中变量的存放次序是x->y->z。所以,从理论上来说,只要知道x,y,z其中一个变量的地址和类型,通过指针运算,可找到其他变量。
    <stdarg.h>中定义了如下几个宏:

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

    va_list是指向当前参数的指针,通过这个指针进行取参。
    宏的使用方式如下:

    1. 先定义一个va_list的变量,假设为ap
    2. 使用va_start对ap进行初始化,va_start的第一个参数是ap,第二个参数是变参表中“…”前面的那个参数
    3. 然后调用va_arg获取参数,第一个参数还是ap,第二个参数是要获取的参数的类型,并且ap指向下一个变量
    4. 获取完参数后,使用va_end关掉ap。va_start和va_end通常成对出现。

    例子:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdarg.h>
    
    int my_snprintf(char *dst, int size, char *fmt, ...)
    {
    	int len;
    	va_list argp;
    	va_start(argp, fmt);
    	len = vsnprintf(dst, size, fmt, argp);
    	len = len > size - 1 ? size - 1 : len;
    	va_end(argp);
    	
    	return len;
    }
    
    int main(void)
    {
    	char str[8];
    	int len;
    	
    	len = my_snprintf(str, sizeof(str), "A:%d:%s", 1, "ABCDEFGH");
    	printf("str:%s, len:%d
    ", str, len);
    
    	return 0;
    }
    
  • 相关阅读:
    友盟冲突解决com.umeng.weixin.handler.UmengWXHandler cannot be cast to com.umeng.socialize.handler.UMWXHandler
    插入mysql失败,因为java数据类型是个实体类,加上.id就好了
    app升级注意事项version
    关于ehcache缓存中eternal及timeToLiveSeconds和timeToIdleSeconds的说明
    WinFom解决最小化最大化后重绘窗口造成闪烁的问题
    Redis 发布订阅
    Redis 发布订阅
    ASPxGridView
    ASPxGridView
    C#-WebRequest 超时不起作用
  • 原文地址:https://www.cnblogs.com/shenlinken/p/8099281.html
Copyright © 2011-2022 走看看