C語言 不定引數標準庫 stdarg h

2021-10-07 14:01:43 字數 2323 閱讀 2175

前言:在很多任務程**中,工程師考慮到後續軟體設計的相容性和擴充套件性,在介面函式中時常會使用一些可變引數。一開始全部考慮到這些很難,因為統籌全域性需要經驗和思考來支撐。c語言標準庫為可變引數工具庫提供了支援。

有人建議說,對於函式引數數量最好不要超過4個。這種說法一般都會涉及到硬體平台,對於arm體系結構來說,函式之間相互呼叫遵循的原則是atpcs(arm-thumb procedure call standard。子程式通過暫存器r0 ~ r3來傳遞引數,被呼叫的子程式在返回前無需恢復暫存器r0 ~ r3的內容。也就是說,在該硬體結構體系下,如果函式引數不大於4個,那麼一開始所有傳入引數會被複製到這些暫存器當中,在執行指令的過程中,無需頻繁再次從儲存器中讀入資料,極大的提高了指令的執行效率。如果函式傳入引數數量大於4個,鑑於cpu中暫存器資源受限,會把變數從記憶體到暫存器之間不斷換入換出,影響指令執行效率。

對於函式的引數列表來說,所有傳入引數的儲存都是從右往左依次入棧儲存。呼叫不定引數的函式列表,不定引數一般都處於最右邊,因此不定引數會先入棧,處於棧底位置。我們都知道在c語言儲存中,兩個貫穿始終的概念是起始位址和偏移量。對於尋找不定引數,我們會關注它儲存的起始位址以及它是什麼型別(偏移量)的變數。

變數描述

va_list

乙個適用於va_start(),va_arg(),va_end()巨集函式儲存資訊的資料型別

stdarg.h庫檔案定義了三個巨集,這三個巨集可用於在引數個數未知(即在引數個數可變)時,獲取函式中的引數。可變引數的函式通常在引數列表的末尾是用…定義的。巨集描述

void va_start(va_list ap,last_arg)

這個巨集初始化ap變數,與va_arg和va_end一起使用

type va_arg(va_list ap,type)

這個巨集檢索引數列表中型別為type的下乙個引數

void va_end(va_list ap)

這個巨集允許使用了va_start巨集帶有可變引數的返回,如果在從函式返回之前沒有呼叫va_end,則結果為未定義

下面是乙個使用不定引數的函式的**例項分析。

int

task_post_event

(char

*name,

int argc,..

.)param =

va_arg

(argptr,

int);if

(param >=32)

else

va_end

(argptr)

;return msg_no_error;

}

使用不定引數在宣告時用 … 代替,且位置一定要在函式頭的最右邊。並且它之前一定至少有乙個形參(用於找到引數棧位置)。

見上**:va_list argptr;

定義乙個變數型別。之前有在其他的文章中分析過,對於乙個硬體體系結構和編譯器已經確定的程式來說,不管什麼資料型別,其位址儲存大小都是確定的(即指標儲存容量大小)。所以,va_list其實是分配了乙個未知資料型別的指標變數的儲存空間。

見上**:va_start(argptr, argc);

執行該條語句,相當於argptr = (va_list)&argc + _intsizeof(argc),argptr指向引數argc之後的那個引數的位址,即argptr指向第乙個可變引數在棧的位址。

見上**:param = va_arg(argptr, int);

執行該條語句,相當於( *(int *)((argptr += _intsizeof(int)) - _intsizeof(int)) )取出當前argptr 指標所指的值賦給param,並使argptr 指向下乙個引數。

若之後的引數型別為其他型別,則可以依次呼叫該語句取出,如:

a = va_arg(argptr, char);

b = va_arg(argptr,char*);

c = va_arg(argptr,float);

見上**:va_end(argptr);

清空 va_list argptr

注:va_start和va_end必須成對出現使用(指標變數有分配有釋放)。

C語言不定引數

最近,遇到乙個c語言的不定引數問題。其實,對於c語言的不定引數問題,只需要三個函式就可以搞定了。這三個函式的標頭檔案是,其實下面的三個函式都是乙個巨集定義 macro 這三個函式是 void va start va list ap,last type va arg va list ap,type v...

C語言基礎 不定引數

在這一節裡我們來學習c語言中另外乙個重要的機制,不定引數。不定引數是指函式可以接收不確定個數的引數,不定引數用.來表示,它必須要寫在正常參數列的後面,例如我們熟知的printf函式 int printf char fmt,printf的第乙個引數為char fmt,後面則是不定引數。它表示可以接收任...

C語言不定引數函式

眾所周知,c語言不支援函式過載,支援函式過載的是c 究其原因,c語言在編譯函式之後,將 函式名 存放到函式庫,而c 在編譯函式之後,將 函式名 引數型別 引數型別 存放到函式庫 但是,在查詢fcntl函式時,卻發現其函式原型有多個 int fcntl int fd,int cmd int fcntl...