zoukankan      html  css  js  c++  java
  • C语言可变参数,参数传递

    C语言可变参数,参数传递 - eureka_ - 博客园

    C语言可变参数,参数传递

    1、函数形参的存储

    函数形参在函数中存储是按照栈的方式来存储的

    实例:

    复制代码
    #include <stdio.h>
    void fun(int a0,int a1,int a2, int a3)
    {
        int *temp;
        temp=&a0;
        int i;
        for(i=0;i<4;i++){
            printf("%d\t",*temp++);
        }
    }
    
    int main(){
        fun(1,2,3,4);
        getchar();
        return 0;
    }
    复制代码

    函数输出为:

    1  2  3  4

    2、一般函数的定义在内存中的存储方式

    一般的变量定义之后,相同的变量类型存储在相邻的一块内存

    例子:

    复制代码
    #include <stdio.h>
    int main()
    {
        int a0=1;
        char c0='a';
        double d0=1.1;
        char c1='b';
        double d1=2.2;
        int a1=2;
      int a2=3;
        int *pint = &a0;
        char *pch = &c0;
        double *pd = &d0;
    
    
        printf("%p:%d\n", pint, *pint);
        pint++;
        printf("%p:%d\n", pint, *pint);
        pint++;
        printf("%p:%d\t%p\n", pint, *pint);
    
        printf("%p:%c\n", pch, *pch);
        pch++;
        printf("%p:%c\n", pch, *pch);
    
        printf("%p:%.2f\n", pd, *pd);
        pd++;
        printf("%p:%.2f\n", pd, *pd);
    }
    复制代码

    输出:

    0xbf944c54:1
    0xbf944c58:2
    0xbf944c5c:3
    0xbf944c6e:a
    0xbf944c6f:b
    0xbf944c40:1.10
    0xbf944c48:2.20

    **这个结论只是对于我自己的编译器的结果,具体可能对于另外一个编译器的输出有有可能不一样,而且,如果把有变量没有使用过的话,编译器有可能丢弃它(自己的猜想而已,等过阵子研究《深入理解计算机系统》的时候在研究这个问题)。

    3、C语言给我们的可变形参va_list

    头文件stdarg.h

    下面定义了四个宏:

    1. va_list

    在stdarg.h中定义:typedef char  *   va_list;

    2. void va_start(va_list ap,last);

    这是第一个调用的宏,last是可变参数的前一个确定的参数。因此只有可变参数的函数是不允许的,如fun(...)是不合法的。

    #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )              //第一个可选参数地址

    3. void va_arg(va_list ap, type);

    返回当前参数并且使ap指向下一个参数,type是明确的类型名,就是获取的类型,不是。

    #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数地址

    4. void va_end(va_list ap);

    有va_start就必须有va_end,作用是使释放ap

    #define va_end(ap)       ( ap = (va_list)0 )                               // 将指针置为无效

    4. void va_copy(va_list dest, va_list src);

    每次调用va_copy时也必须要有va_end调用。

    例子:

    复制代码
    #include <stdio.h>
    #include <stdarg.h>
    
    void fun(int a,...){
        va_list ap;
        va_start(ap, a);
        int i;
        for(i=0; i<a; i++){
            printf("%d\t",va_arg(ap,int));
        }
        putchar('\n');
        va_end(ap);
    }
    
    int main(){
        fun(4,1,2,3,4);
        printf("--------------------------------\n");
        fun(4,1,2,"ab","cd");
        return 0;
    }
    复制代码

    输出:

    1 2 3 4
    --------------------------------
    1 2 134514184 134514181

  • 相关阅读:
    HDU 4462 DFS
    HorizontalScrollView的使用演示样例
    编程之美读书笔记1.1——让CPU占用率曲线听你的指挥
    flume 日志导入elasticsearch
    2、COCOS2D-X内存管理机制
    cocos2d js ScrollView的使用方法
    程序中涉及到时间的相关问题
    【转】Android的onCreateOptionsMenu()创建菜单Menu详解
    【转】Android 菜单(OptionMenu)大全 建立你自己的菜单--不错
    【转】onPrepareOptionsMenu 和onCreateOptionsMenu 的区别
  • 原文地址:https://www.cnblogs.com/lexus/p/2581107.html
Copyright © 2011-2022 走看看