c语言可变入参中的每个参数的类型可以不同,编程入门:浅谈C语言的可变参数
C語(yǔ)言中有些函數(shù)使用可變參數(shù),比如常見(jiàn)的int printf( const char* format, ...),第一個(gè)參數(shù)format是固定的,其余的參數(shù)的個(gè)數(shù)和類型都不固定。
C語(yǔ)言用va_start等宏來(lái)處理這些可變參數(shù)。這些宏看起來(lái)很復(fù)雜,其實(shí)原理挺簡(jiǎn)單,就是根據(jù)參數(shù)入棧的特點(diǎn)從最靠近第一個(gè)可變參數(shù)的固定參數(shù)開(kāi)始,依次獲取每個(gè)可變參數(shù)的地址。下面我們來(lái)分析這些宏。
在stdarg.h頭文件中,針對(duì)不同平臺(tái)有不同的宏定義,我們選取X86平臺(tái)下的宏定義:
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)宏是為了考慮那些內(nèi)存地址需要對(duì)齊的系統(tǒng),從宏的名字來(lái)應(yīng)該是跟sizeof(int)對(duì)齊。一般的sizeof(int)=4,也就是參數(shù)在內(nèi)存中的地址都為4的倍數(shù)。比如,如果sizeof(n)在1-4之間,那么_INTSIZEOF(n)=4;如果sizeof(n)在5-8之間,那么_INTSIZEOF(n)=8。
為了能從固定參數(shù)依次得到每個(gè)可變參數(shù),va_start,va_arg充分利用下面兩點(diǎn):
1. C語(yǔ)言在函數(shù)調(diào)用時(shí),先將最后一個(gè)參數(shù)壓入棧
2. X86平臺(tái)下的內(nèi)存分配順序是從高地址內(nèi)存到低地址內(nèi)存
高位地址
第N個(gè)可變參數(shù)
。。。
第二個(gè)可變參數(shù)
第一個(gè)可變參數(shù)????? ? ap
固定參數(shù)?????????? ? v
低位地址
由上圖可見(jiàn),v是固定參數(shù)在內(nèi)存中的地址,在調(diào)用va_start后,ap指向第一個(gè)可變參數(shù)。這個(gè)宏的作用就是在v的內(nèi)存地址上增加v所占的內(nèi)存大小,這樣就得到了第一個(gè)可變參數(shù)的地址。
接下來(lái),可以這樣設(shè)想,如果我能確定這個(gè)可變參數(shù)的類型,那么我就知道了它占用了多少內(nèi)存,依葫蘆畫瓢,我就能得到下一個(gè)可變參數(shù)的地址。
讓我再來(lái)看看va_arg,它先ap指向下一個(gè)可變參數(shù),然后減去當(dāng)前可變參數(shù)的大小即得到當(dāng)前可變參數(shù)的內(nèi)存地址,再做個(gè)類型轉(zhuǎn)換,返回它的值。
要確定每個(gè)可變參數(shù)的類型,有兩種做法,要么都是默認(rèn)的類型,要么就在固定參數(shù)中包含足夠的信息讓程序可以確定每個(gè)可變參數(shù)的類型。比如,printf,程序通過(guò)分析format字符串就可以確定每個(gè)可變參數(shù)大類型。
最后一個(gè)宏就簡(jiǎn)單了,va_end使得ap不再指向有效的內(nèi)存地址。
看了這幾個(gè)宏,不禁讓我再次感慨,C語(yǔ)言太靈活了,而且代碼可以寫得非常簡(jiǎn)潔,雖然有時(shí)候讓人看得不是很明白,但是一旦明白 過(guò)來(lái),你肯定會(huì)為它擊掌叫好!
其實(shí)在varargs.h頭文件中定義了UNIX System V實(shí)行的va系列宏,而上面在stdarg.h頭文件中定義的是ANSI C形式的宏,這兩種宏是不兼容的,一般說(shuō)來(lái),我們應(yīng)該使用ANSI C形式的va宏。
總結(jié)
以上是生活随笔為你收集整理的c语言可变入参中的每个参数的类型可以不同,编程入门:浅谈C语言的可变参数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 哈尔滨工业大学计算机学院-模式识别-课程
- 下一篇: c语言中指,浅析C语言中指与数组.doc