编程入门:浅谈C语言的可变参数

2016-02-19 13:05 7 1 收藏

下面请跟着图老师小编一起来了解下编程入门:浅谈C语言的可变参数,精心挑选的内容希望大家喜欢,不要忘记点个赞哦!

【 tulaoshi.com - 编程语言 】

C语言中有些函数使用可变参数,比如常见的int printf( const char* format, ...),第一个参数format是固定的,其余的参数的个数和类型都不固定。  C语言用va_start等宏来处理这些可变参数。这些宏看起来很复杂,其实原理挺简单,就是根据参数入栈的特点从最靠近第一个可变参数的固定参数开始,依次获取每个可变参数的地址。下面我们来分析这些宏。  在stdarg.h头文件中,针对不同平台有不同的宏定义,我们选取X86平台下的宏定义:

  typedef char *  va_list;  #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 )   _INTSIZEOF(n)宏是为了考虑那些内存地址需要对齐的系统,从宏的名字来应该是跟sizeof(int)对齐。一般的sizeof(int)=4,也就是参数在内存中的地址都为4的倍数。比如,假如sizeof(n)在1-4之间,那么_INTSIZEOF(n)=4;假如sizeof(n)在5-8之间,那么_INTSIZEOF(n)=8。  为了能从固定参数依次得到每个可变参数,va_start,va_arg充分利用下面两点:  1. C语言在函数调用时,先将最后一个参数压入栈  2. X86平台下的内存分配顺序是从高地址内存到低地址内存  高位地址  第N个可变参数  。。。  第二个可变参数  第一个可变参数      ? ap  固定参数           ? v  低位地址  由上图可见,v是固定参数在内存中的地址,在调用va_start后,ap指向第一个可变参数。这个宏的作用就是在v的内存地址上增加v所占的内存大小,这样就得到了第一个可变参数的地址。  接下来,可以这样设想,假如我能确定这个可变参数的类型,那么我就知道了它占用了多少内存,依葫芦画瓢,我就能得到下一个可变参数的地址。  让我再来看看va_arg,它先ap指向下一个可变参数,然后减去当前可变参数的大小即得到当前可变参数的内存地址,再做个类型转换,返回它的值。  要确定每个可变参数的类型,有两种做法,要么都是默认的类型,要么就在固定参数中包含足够的信息让程序可以确定每个可变参数的类型。比如,printf,程序通过分析format字符串就可以确定每个可变参数大类型。  最后一个宏就简单了,va_end使得ap不再指向有效的内存地址。  看了这几个宏,不禁让我再次感慨,C语言太灵活了,而且代码可以写得非常简洁,虽然有时候让人看得不是很明白,但是一旦明白 过来,你肯定会为它击掌叫好!  其实在varargs.h头文件中定义了UNIX System V实行的va系列宏,而上面在stdarg.h头文件中定义的是ANSI C形式的宏,这两种宏是不兼容的,一般说来,我们应该使用ANSI C形式的va宏。
  

来源:http://www.tulaoshi.com/n/20160219/1602939.html

延伸阅读
作为C++标准不可缺少的一部分,STL应该是渗透在C++程序的角角落落里的。STL不是实验室里的宠儿,也不是程序员桌上的摆设,她的激动人心并非昙花一现。本教程旨在传播和普及STL的基础知识,若能借此机会为STL的推广做些力所能及的事情,到也是件让人愉快的事情。 1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL "什...
导读 C#是Microsoft开发的一种新语言,它和C/C++一样强大,和Java一样提供丰富的网络编程支持和自动内存管理,和VB一样简单易用。本文的目的是为尚未接触过C#的程序员介绍这种编程语言,是一个基础的入门教程。 作者:仙人掌工作室 2001-02-20 原文出处:http://journal.iftech.com/articles/0011_joey_CSharp/ C#读作“C ...
从程序流程的角度来看,程序可以分为三种基本结构, 即顺序结构、分支结构、循环结构。 这三种基本结构可以组成所有的各种复杂程序。C语言提供了多种语句来实现这些程序结构。 本文将介绍这些基本语句及其应用,使读者对C程序有一个初步的熟悉, 为以后的学习打下基础。 C程序的语句 C程序的执行部分是由语句组成的。 程序的功能...
我们创建的第一个类是Shape。这是一个抽象类,因为我们不想创建这个类的实例,我们要创建的是它的派生类的实例。我们从所有的形状(圆、长方形、正方形)提取出共同特征到Shape类。Shape类有一个实例变量color,它的变量声明中带有protected修饰符。protected修饰符表示这个变量只能在类的内部或者该类的派生类中访问。紧接这个变量声明的就是Sh...
下面这个例子示范如何创建和使用用户定义的类以及如何创建动态链接库。利用文本编辑器创建两个文件。第一个是Apple.cs,内容如下: public class Apple { private string variety = ""; public Apple(string appleVariety) { this.variety = appleVariety; } public void outputVariety() { System.Console.WriteLine(variety); } } ...

经验教程

473

收藏

36
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部