網站首頁 編程語言 正文
Intro
有一天看C代碼看到某個方法有這樣的定義:在函數形參列表處,有...
的寫法,就像Java中的不定參數那樣。
如:
int printf(const char * __restrict, ...) __printflike(1, 2); int scanf(const char * __restrict, ...) __scanflike(1, 2);
那么C語言中的不定參數特性,是怎樣使用的呢,以及我們如何利用該特性,封裝自己的函數?
語法測試
依賴庫
需要用到 stdarg.h
中的三個函數:
#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> // 聲明列表的結束值 #define ARGUMENTS_END_VALUE -1 void printMultiArgs(int firstArgs, ...) { // 聲明參數列表的變量 va_list ap; // 初始化參數列表 va_start(ap, firstArgs); printf("%d\n", firstArgs); int currValue; while ((currValue = va_arg(ap, int)) != ARGUMENTS_END_VALUE) { printf("%d\n", currValue); } // 結束參數列表 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; }
用兩種方式封裝函數:對多個int值求和
// // main.c // C不定參數 // // 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> // 聲明列表的結束值 #define ARGUMENTS_END_VALUE -1 void printMultiArgs(int firstArgs, ...) { // 聲明參數列表的變量 va_list ap; // 初始化參數列表 va_start(ap, firstArgs); printf("%d\n", firstArgs); int currValue; while ((currValue = va_arg(ap, int)) != ARGUMENTS_END_VALUE) { printf("%d\n", currValue); } // 結束參數列表 va_end(ap); } /// 對多個int變量求和(需要提前約定好參數結束的標志值 ARGUMENTS_END_VALUE) /// - Parameter firstArgs: <#firstArgs description#> int sum1(int firstArgs, ...) { int result = 0; va_list ap; va_start(ap, firstArgs); result+= firstArgs; // 手動處理第一個參數 int currValue; while ((currValue = va_arg(ap, int)) != ARGUMENTS_END_VALUE) { result += currValue; } va_end(ap); return result; } /// 對多個int變量求和(需要主動本方法:不定參數的個數是多少) /// - Parameters: /// - count: 不定參數的個數 /// - firstArgs: 第一個參數,顯式的形參 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; }
執行結果:
總結
- 需要引入頭文件 #include <stdarg.h>
- 一個新類型,三個新函數
- 類型 va_list
- 函數,其中 ap 為 va_list 類型的變量。
- va_start(ap, param) param為不定參數列表的第一個參數。
- va_arg(ap, type) 不定參數中變量的類型嗎,如int, short, long 等。
- va_end(ap)
- 如何確定 va_arg 的size/有多少個元素? 沒有原生的屬性/變量可以告訴我們。
- 約定一個值作為 end_value ,而且要保證:這個值不會出現在傳入的多個參數值中。
- 在咱自己封裝的函數中,新增一個參數用于告知被調函數內部:本次不定參數的size是多少。
- 注意不定參數的類型匹配。
總結?
原文鏈接:https://blog.csdn.net/wuyujin1997/article/details/128752337
相關推薦
- 2022-06-06 Kafka在Zookeeper中存儲的信息有哪些?
- 2022-04-19 C++中拷貝構造函數的使用_C 語言
- 2022-06-06 淺談Redis?中的過期刪除策略和內存淘汰機制_Redis
- 2022-08-01 C語言深入探索遞歸的特點_C 語言
- 2022-10-02 iOS實現簡易的抽屜效果_IOS
- 2022-07-02 python之NAN和INF值處理方式_python
- 2023-06-20 C++模擬實現vector示例代碼圖文講解_C 語言
- 2022-08-28 SpringCloudAlibaba-3.分布式事務(Seata)
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支