zoukankan      html  css  js  c++  java
  • 不定参数函数的实现

    函数的代码是在编译时候生成的,对于带有不定参数个数(甚至对于每一个参数对应的类型也不也一样)的函数,编译器怎么在支持这样的函数。 

    1 #include < stdio.h>
    2 #include < string.h>
    3 #include < stdarg.h>
    4
    6 int t(...)
    7 {
    8   return 0;
    9 }
    10 /* 函数原型声明,至少需要一个确定的参数,注意括号内的省略号 */
    11 int demo( char *, ...) ;
    12
    13
    14 void main( void )
    15
    16 {
    17 demo("DEMO"," This"," is "," a ","demo!", "\0");
    18 }
    19
    20 int demo( char *msg, ... )
    21 {
    22 va_list argp; /* 定义保存函数参数的结构 */
    23 int argno = 0; /* 纪录参数个数 */
    24 char *para; /* 存放取出的字符串参数 */
    25
    26 va_start( argp, msg );
    27 while (1)
    28 {
    29 para = va_arg( argp, char *);
    30 if ( strcmp( para, "\0" ) == 0 ) /* 采用空串指示参数输入结束 */
    31 break;
    32
    33 printf("参数 #%d 是: %s\n", argno, para);
    34 argno++;
    35 }
    36 va_end( argp ); /* 将argp置为NULL */
    37
    38 return 0;
    39 }

    有意思是介绍几个宏

    先看这个:

    #define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

    这个是为了内存对齐,可以将n这个类型长度转换为sizeof(int)的倍数长度。 比如sizeof (n)=9 ,sizeof(int)=4,

    那么 _INTSIZEOF(n) = ( 9 + 4 -1)&~(4 -1) = 12/3 = 4. 也就是将 9 转换为 12,为边界对齐加了一个3.

    关一个这个的证明在这:

    蛮经典的:http://blogold.chinaunix.net/u/1129/showart_397677.html

     //#define va_start _crt_va_start
     //#define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
     //#define _ADDRESSOF(v)   ( &reinterpret_cast<const char &>(v) )

    //#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

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

    NOTE:

    1.从va_start宏依赖第一个函数地址,得到下一个函数的地址。这也就是为什么不定参数的函数需要至少一个参数。

    2.对于函数参数的个数的判读,需要自己。如果printf里面第一个参数定义可以得到后面的参数个数,或者最后一个参数要有定义。

  • 相关阅读:
    java IO流之详细总结
    位运算了解与复习多线程
    java 常见面试题总结(一)
    复习集合框架
    【面试题】java中高以上必会技能
    python-项目流程分析及优化查询方法
    python-day97--django-ModelForm
    python-day97--git协同开发
    python-day96--git版本控制
    python-day91--同源策略与Jsonp
  • 原文地址:https://www.cnblogs.com/zhyg6516/p/2021276.html
Copyright © 2011-2022 走看看