C语言补丁原理,C语言可变长參数实现原理
(1)????? C語(yǔ)言可變參數(shù)
我們能夠從C語(yǔ)言的printf得出可變參數(shù)的作用。printf函數(shù)的原型例如以下:
int printf ( const char * format, ... );
通過(guò)使用可變個(gè)數(shù)參數(shù),就是傳入的參數(shù)個(gè)數(shù)是可變的,如printf須要依據(jù)format實(shí)參傳入多個(gè)實(shí)參。
(2)????? C語(yǔ)言可變參數(shù)的使用
以下一個(gè)函數(shù)myprintf是自己實(shí)現(xiàn)的比較簡(jiǎn)單的printf函數(shù)。不完整可是能夠說(shuō)明可變參數(shù)的使用方法。
/*
* Author: guojun07
*/
#include
#include
#include
#include
void myprintf(char *format, ...) {
va_list ap;
int pos = 0;
int int_val = 0;
float f_val;
char buf[64];
memset(buf, 0, 64);
// 得到全部的參數(shù)放到下一個(gè)list中ap中
va_start(ap, format);
while (format[pos] != ' ') {
// 推斷'%'。表示要得到下一個(gè)參數(shù)
if (format[pos] == '%') {
pos ++;
switch(format[pos]) {
case 'd':
case 'u':
// 得到ap中的下一個(gè)參數(shù)
int_val = va_arg(ap, int);
sprintf(buf, "%d", int_val);
// 將數(shù)據(jù)寫(xiě)到標(biāo)準(zhǔn)輸出
write(STDOUT_FILENO, buf, strlen(buf));
memset(buf, 0, 64);
pos ++;
break;
case 'f':
// 得到ap中的下一個(gè)參數(shù)
f_val = (float)va_arg(ap, double);
sprintf(buf, "%f", f_val);
// 將數(shù)據(jù)寫(xiě)到標(biāo)準(zhǔn)輸出
write(STDOUT_FILENO, buf, strlen(buf));
memset(buf, 0, 64);
pos ++;
break;
default:
break;
}
} else {
write(STDOUT_FILENO, &(format[pos]), 1);
pos ++;
}
}
}
int main(void){
myprintf("this is a testing, i = %d, u = %u, f = %f
", -1, 5, 0.2);
return 0;
}
程序的數(shù)據(jù)結(jié)果例如以下:
guojun8@guojun8-desktop:~/test/valist$ ./main
this is a testing, i = -1, u = 5, f = 0.200000
(3)????? 實(shí)現(xiàn)
以下介紹C語(yǔ)言可變長(zhǎng)度參數(shù)的實(shí)現(xiàn)。事實(shí)上現(xiàn)與一個(gè)數(shù)據(jù)結(jié)構(gòu)(va_list)和三個(gè)宏(va_start, va_end, va_arg)相關(guān),從源代碼中能夠看到這些實(shí)現(xiàn)以下的來(lái)自linux內(nèi)核源代碼中的文件(include/acpi/platform/acenv.h)
#ifndef _VALIST
#define _VALIST
typedef char *va_list;
#endif??????? /* _VALIST */
/*
* Storage alignment properties
*/
#define? _AUPBND??????????????? (sizeof (acpi_native_int) - 1)
#define? _ADNBND??????????????? (sizeof (acpi_native_int) - 1)
/*
* Variable argument list macro definitions
*/
#define _bnd(X, bnd)??????????? (((sizeof (X)) + (bnd)) & (~(bnd)))
#define va_arg(ap, T)?????????? (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
#define va_end(ap)????????????? (void) 0
#define va_start(ap, A)???????? (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
a)???????? va_list
從實(shí)現(xiàn)中能夠看出va_list類(lèi)型實(shí)際上就是一個(gè)指針。
b)??????? va_start
這個(gè)宏的作用是將T所指向的參數(shù)后面的內(nèi)容放到ap中。當(dāng)中_bnd (A,_AUPBND)是返回A的size并與系統(tǒng)的機(jī)器位數(shù)對(duì)齊。由于參數(shù)在棧中的地址一定是與系統(tǒng)的字長(zhǎng)對(duì)齊的,當(dāng)中acpi_native_int就表示機(jī)器字長(zhǎng)。
c)???????? va_end
這個(gè)宏的作用就是返回0。
d)??????? va_arg
這個(gè)宏的作用是取得ap指向的當(dāng)前的參數(shù),并將ap指向參數(shù)列表中的下一個(gè)參數(shù)。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的C语言补丁原理,C语言可变长參数实现原理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 掌机汉化辅助工具——WQSG 最佳伴侣发
- 下一篇: 源码安装httpd