-
這東西基本沒用。
va_list arguments;
va_start
你去檢查 API。 您可以找到這兩個函式的定義!
-
前言:
有時我們需要乙個能夠支援變數引數的函式介面來提高它們的泛化能力,比如定義乙個求和函式,將所有傳入的引數求和並返回它們,而 C 提供了一種方法來幫助我們實現這一點。
原則:
如果我們能知道變數引數列表前乙個引數的位址和型別,我們就可以知道變數引數列表的第乙個位址,然後根據每個引數的型別提取相應的資料。 簡單來說,堆疊中的資料是根據指定型別的大小依次取出的。
具體實施:步驟分析:
-
VA 列表用於訪問 variadics。 VA start 用於初始化 VA 列表變數。 VA arg 用於獲取下乙個變數。
VA end 用於取消初始化 VA 列表變數。 va arg 函式根據當前給定的型別獲取當前指向的函式的引數,並在其中遞增指標以指向下乙個引數。
例如,va arg(arguments, char*)。
這裡我們假設當前引數的型別為 char*,並修改內部指標以遞增 sizeof(char*) 以指向下乙個引數。 獲得的值可能指向"beijing"或"olympic games"指標。
va_arg(arguments, int)
假設當前引數的型別為 int,並修改內部指標以遞增 sizeof(int) 以指向下乙個引數。 此處的可能值為 2000(均為 2000)。
注意這是乙個非常低階的函式,呼叫 va arg 時指定的引數型別需要和傳遞時一樣,否則可能會崩潰。 還應該注意的是,由於 char 等型別在傳遞給此類函式時會轉換為 int,因此在呼叫 va arg 時必須使用 int 而不是 char 來提取引數,如本文所述。
-
C語言中的變數引數函式主要是通過va列表巨集和幾個相關操作的巨集來實現的。
1. 涉及的巨集和描述:
所有相關的巨集都在 中定義。
1. VA 列表:指向變數列表的指標。
4. VA END:清除變數引數的 VA 列表。
變數引數函式的實現就是使用這四個巨集。
2. 示例:
在實際應用中,經常會出現得到幾個數字的最大值的情況,當數字比較大時,一般通過乙個陣列來實現,但是當數字較小時,一般寫乙個最大值函式。 傳統的方法是使用幾個 max 的數字,只需寫入幾個引數,就可以實現乙個可變引數函式,第乙個引數指定總共有多少資料,後面的引數是要比較的值。
#include
#include
int max(int n, .可變引數函式。
測試 1、2、3 和 4 值以找到最大值。
測試結果:1299
-
1.標準C庫中的三個巨集僅用於確定可變引數列表中每個引數的記憶體位址,編譯器並不知道引數的實際數量。
2.在實際應用中,程式設計師必須考慮確定引數數量的方法,例如:
這就是 printf 函式用於在固定引數中設定標誌的方式。
在預設乙個特殊的結束標誌時,即多輸入乙個變數引數,呼叫時應將最後乙個變數引數的值設定為這個特殊值,並根據函式體中的這個值判斷是否已經到達了引數的末尾。 本文前面的**就是採用這種方法。
無論哪種方式,程式設計師都應該在文件中告訴呼叫者他們的約定。
堆疊增長的方向。
引數放入堆疊的順序。
CPU 對齊。
記憶體位址的表示式。
結合源**,我們可以看到 va list 的實現是由 決定的,intsizeof(n) 的引入是由 決定的,他和一起確定 va start 的實現,最後 va end 的存在就是乙個好的程式設計風格的體現,不再使用的指標被設定為 null, 這可以防止將來的誤操作。
4.獲取位址後,結合引數型別,程式設計師可以正確處理引數。
-
variable argument 的英文表示式為: variable argument
在定義函式時,它用三個點來定義'.'表示形式,用逗號與其他引數分隔。
變數引數的特徵不像固定引數那樣一一對應,也不像固定引數那樣有固定的引數型別和引數名稱; 可變引數的數量不是。
當然,它可以是單個引數或多個引數; 可變引數中的每個引數可以是不同或相同的型別; 可變引數的每個引數都沒有。
實際名稱與之相對應。
可以看出,變數引數的形式非常自由和彈性。 因此,它為有天賦的程式設計師提供了更多的想象和發展空間。
下面介紹變數引數的幾個方面。
1)變數引數的儲存形式。
眾所周知,一般函式的引數是區域性變數。 區域性變數是儲存在記憶體中的堆疊(所謂堆疊:由編譯器自動分配和釋放,儲存函式的引數值、區域性變數的值等)。
它的行為類似於資料結構中的堆疊。 ).調壓器也儲存在儲存器堆疊中。
在儲存函式的引數時,編譯器將堆疊從函式引數的右到左逐個按下,從而保證堆疊的頂部是函式引數的第乙個引數(從左到右)。80x86 平台下的記憶體分配順序是從高位址記憶體到低位址記憶體。