C語(yǔ)言中不定參數(shù)?...?的語(yǔ)法以及函數(shù)封裝
Intro
有一天看C代碼看到某個(gè)方法有這樣的定義:在函數(shù)形參列表處,有...
的寫法,就像Java中的不定參數(shù)那樣。
如:
int printf(const char * __restrict, ...) __printflike(1, 2); int scanf(const char * __restrict, ...) __scanflike(1, 2);
那么C語(yǔ)言中的不定參數(shù)特性,是怎樣使用的呢,以及我們?nèi)绾卫迷撎匦?,封裝自己的函數(shù)?
語(yǔ)法測(cè)試
依賴庫(kù)
需要用到 stdarg.h
中的三個(gè)函數(shù):
#define va_start(ap, param) __builtin_va_start(ap, param) #define va_end(ap) __builtin_va_end(ap) #define va_arg(ap, type) __builtin_va_arg(ap, type)
新函數(shù)使用測(cè)試:遍歷并打印不定參數(shù)中的值
主要是測(cè)試一下上面提到的三個(gè)庫(kù)函數(shù)的使用。
#include <stdio.h> #include <stdarg.h> // 聲明列表的結(jié)束值 #define ARGUMENTS_END_VALUE -1 void printMultiArgs(int firstArgs, ...) { // 聲明參數(shù)列表的變量 va_list ap; // 初始化參數(shù)列表 va_start(ap, firstArgs); printf("%d\n", firstArgs); int currValue; while ((currValue = va_arg(ap, int)) != ARGUMENTS_END_VALUE) { printf("%d\n", currValue); } // 結(jié)束參數(shù)列表 va_end(ap); } int main(int argc, const char * argv[]) { printMultiArgs(1,2,3,4,5,6,7,8,9, ARGUMENTS_END_VALUE); return 0; }
用兩種方式封裝函數(shù):對(duì)多個(gè)int值求和
// // main.c // C不定參數(shù) // // Created by wuyujin1997 on 2023/1/23. // //#define va_start(ap, param) __builtin_va_start(ap, param) //#define va_end(ap) __builtin_va_end(ap) //#define va_arg(ap, type) __builtin_va_arg(ap, type) #include <stdio.h> #include <stdarg.h> // 聲明列表的結(jié)束值 #define ARGUMENTS_END_VALUE -1 void printMultiArgs(int firstArgs, ...) { // 聲明參數(shù)列表的變量 va_list ap; // 初始化參數(shù)列表 va_start(ap, firstArgs); printf("%d\n", firstArgs); int currValue; while ((currValue = va_arg(ap, int)) != ARGUMENTS_END_VALUE) { printf("%d\n", currValue); } // 結(jié)束參數(shù)列表 va_end(ap); } /// 對(duì)多個(gè)int變量求和(需要提前約定好參數(shù)結(jié)束的標(biāo)志值 ARGUMENTS_END_VALUE) /// - Parameter firstArgs: <#firstArgs description#> int sum1(int firstArgs, ...) { int result = 0; va_list ap; va_start(ap, firstArgs); result+= firstArgs; // 手動(dòng)處理第一個(gè)參數(shù) int currValue; while ((currValue = va_arg(ap, int)) != ARGUMENTS_END_VALUE) { result += currValue; } va_end(ap); return result; } /// 對(duì)多個(gè)int變量求和(需要主動(dòng)本方法:不定參數(shù)的個(gè)數(shù)是多少) /// - Parameters: /// - count: 不定參數(shù)的個(gè)數(shù) /// - firstArgs: 第一個(gè)參數(shù),顯式的形參 int sum2(int count, int firstArgs, ...) { int result = 0; va_list ap; va_start(ap, firstArgs); result += firstArgs; for (int i = 1; i < count; i++) { int currValue = va_arg(ap, int); // printf("%d %d\n", i, currValue); result += currValue; } va_end(ap); return result; } int main(int argc, const char * argv[]) { printMultiArgs(1,2,3,4,5,6,7,8,9, ARGUMENTS_END_VALUE); printf("sum1 %d\n", sum1(1,2,3,4,5,6,7,8,9, ARGUMENTS_END_VALUE)); int LENGTH = 9; printf("sum2 %d\n", sum2(LENGTH, 1,2,3,4,5,6,7,8,9, ARGUMENTS_END_VALUE)); return 0; }
執(zhí)行結(jié)果:
總結(jié)
- 需要引入頭文件 #include <stdarg.h>
- 一個(gè)新類型,三個(gè)新函數(shù)
- 類型 va_list
- 函數(shù),其中 ap 為 va_list 類型的變量。
- va_start(ap, param) param為不定參數(shù)列表的第一個(gè)參數(shù)。
- va_arg(ap, type) 不定參數(shù)中變量的類型嗎,如int, short, long 等。
- va_end(ap)
- 如何確定 va_arg 的size/有多少個(gè)元素? 沒(méi)有原生的屬性/變量可以告訴我們。
- 約定一個(gè)值作為 end_value ,而且要保證:這個(gè)值不會(huì)出現(xiàn)在傳入的多個(gè)參數(shù)值中。
- 在咱自己封裝的函數(shù)中,新增一個(gè)參數(shù)用于告知被調(diào)函數(shù)內(nèi)部:本次不定參數(shù)的size是多少。
- 注意不定參數(shù)的類型匹配。
總結(jié)
到此這篇關(guān)于C語(yǔ)言中不定參數(shù) ... 的語(yǔ)法以及函數(shù)封裝的文章就介紹到這了,更多相關(guān)C語(yǔ)言不定參數(shù) ...內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++下如何將TensorFlow模型封裝成DLL供C#調(diào)用
這篇文章主要介紹了C++下如何將TensorFlow模型封裝成DLL供C#調(diào)用問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11聊聊Qt+OpenCV聯(lián)合開(kāi)發(fā)之圖像的創(chuàng)建與賦值問(wèn)題
這篇文章主要介紹了Qt+OpenCV聯(lián)合開(kāi)發(fā)之圖像的創(chuàng)建與賦值問(wèn)題,給大家介紹了圖像的克隆及拷貝問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01簡(jiǎn)單說(shuō)說(shuō)STL的內(nèi)存管理
<STL 源碼剖析>將其描述為空間配置器,理由是allocator可以將其它存儲(chǔ)介質(zhì)(例如硬盤)做為stl 容器的存儲(chǔ)空間。由于內(nèi)存是allocator管理的主要部分,因此,本文以STL內(nèi)存管理為出發(fā)點(diǎn)介紹allocator2013-09-09C++中利用cout和fstream采用非科學(xué)計(jì)數(shù)法輸出
這篇文章主要介紹了C++中利用cout和fstream采用非科學(xué)計(jì)數(shù)法輸出方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11C++日期與時(shí)間 chrono庫(kù)介紹及使用教程
chrono庫(kù)是C++11中的一個(gè)標(biāo)準(zhǔn)庫(kù),它提供了一系列與時(shí)間相關(guān)的類和函數(shù),用于表示和處理時(shí)間間隔,時(shí)鐘和時(shí)間點(diǎn),C++20新增Calendar,這篇文章主要介紹了C++日期與時(shí)間 chrono庫(kù)介紹及使用,需要的朋友可以參考下2023-12-12OpenCV+Qt實(shí)現(xiàn)圖像處理操作工具的示例代碼
這篇文章主要介紹了利用OpenCV+Qt實(shí)現(xiàn)圖像處理操作工具,可以實(shí)現(xiàn)雪花屏、高斯模糊、中值濾波、毛玻璃等操作,感興趣的可以了解一下2022-08-08