C語言細節 va list, , , 等

2021-07-02 02:55:14 字數 1512 閱讀 9520

c語言中va_list用於引數可變的函式中,提供了讀取每個引數的方式.

#define _valist

typedef char *va_list;

/* 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) (ap = (va_list) null)

#define va_start(ap, a) (void) ((ap) = (((char *) &(a)) + (_bnd (a,_aupbnd))))

va_list實際上是乙個字元型的指標,va_start會將ap指向a的下乙個位置,而va_arg會返回乙個t型別的變數,va_end會將ap賦值為null.

c語言中用…來取消編譯器對函式引數個數和型別的檢查,這時就利用到了va_list

int sprintf(char *buf, const char *fmt, ...)

在c語言的預編譯階段,編譯器會對##,#進行替換,替換的規則是

(1)#define p(a) printf("%s: %d\n",#a,a)

(2)#define xname(n) x##n如果呼叫xname(0)就是x0

具體來說,#將乙個變數名變為字串,##將乙個字串和變數值拼接起來.

在gcc中存在擴充套件#define debug(fmt,...) printk(fmt,##__va_args__ )其中__va_args__代表…的引數,加上##是為了防止__va_args__為空導致編譯出錯.

#define debug(...) printf(__va_args__)

__file__表示所在檔案

__line__表示所在檔案的行數

__ function__表示當前函式

一般用於列印出錯訊息.

#define dprint(fmt,...) printk("%s,%d,%s:"fmt,\__file__\,__line__,\__function__,##\__va_args__)

兩個連續的」會被消除

C語言細節

參考 注釋必須和 一起維護,不應該描述顯而易見的事,或把別的地方已說清楚的東西在說一遍。字面常量沒有語義,也沒有真正的記憶體位址。所以不可以取其位址,也不可以用於初始化普通引用,例如 long r1 40000 但是const long r1 40000 卻是合法的。所以,盡量不要使用字面常量,而應...

C語言細節

a b 先賦值再自增 a b先自增再賦值 float 6 4是1.500000 float 6 4 是1.000000 原始檔.c 目標程式.obj 執行程式.exe 都是二進位制檔案 源程式以ascii 形式存於文字檔案 c程式演算法可無輸入必須要有輸出 三種基本結構可以完成任何複雜的任務 大括號...

C語言細節

1.c誰呼叫了main函式 linux執行乙個程式就是建立乙個新程序,然後把這個程式丟到這個程序中執行直到結束。linux通過.task執行程式,新程序作為命令程序的乙個子程序執行。main函式的返回值最終會返回給父程序。父程序的引數傳遞給子程序。2.void型別的本質 void的意思是乙個變數還不...