C語言可變參數全解

cstdarg(stdarg.h)
可變參數的處理
? ? 這個頭文件定義了一些宏,可以通過這些宏來逐個訪問被調函數的沒有名字的參數列表,這些參數的個數
和類型都是不知道的。
? ? 一個函數可以通過包含一個逗號和三個點(,...)接收可變數量的額外參數,而不需要給出相應的參數定義。
這些可變參數必須出現在常規命名參數的后面。

返回值 函數名 (參數聲明 , ...);
可以通過該頭文件中定義的宏va_start, va_arg和va_end來訪問額外的參數。
*首先,va_start初始化了一個名為va_list的可變參數列表;
*序列的執行va_arg將會按照參數傳遞給函數的順序產生額外參數的值;
*最胡,va_end必須在函數返回之前被執行。

該頭文件包含了一個類型:
va_list 包含可變參數信息的類型。(類型)
三個函數:
va_start ? ? ? ??初始化一個可變參數列表。(宏)
va_arg 獲取下一個參數。 ? ? ? ? ? ? ? ?(宏)
va_end 停止使用可變參數列表。 ? ?(宏)

? ? 一些C編譯器的實現(例如ISO C99兼容的編譯器)同樣也包含一個va_copy宏,用于復制一個va_list對象,
但是這并不是ISO C++標準的一部分。



va_start
void va_start (va_list ap, paramN);
初始化可變參數列表
? ? 初始化最為參數傳入的va_list類型的對象ap,ap保存了通過va_arg獲得參數paramN之后的可變參數的
信息。
? ? 一個函數執行了va_start,就必須在函數返回之前執行va_end。

參數
ap
va_list類型的對象,保存了通過va_arg獲取可變參數的信息。
paramN
函數定義的最后一個命名參數的名字。

返回值


示例

[cpp] view plaincopy
  1. <span?style="font-size:16px;">/*?va_start?example?*/??
  2. #include?<stdio.h>??
  3. #include?<stdarg.h>??
  4. ??
  5. void?PrintFloats?(?int?amount,?...)??
  6. {??
  7. ??int?i;??
  8. ??double?val;??
  9. ??printf?("Floats?passed:?");??
  10. ??va_list?vl;??
  11. ??va_start(vl,amount);??
  12. ??for?(i=0;i<amount;i++)??
  13. ??{??
  14. ????val=va_arg(vl,double);??
  15. ????printf?("\t%.2f",val);??
  16. ??}??
  17. ??va_end(vl);??
  18. ??printf?("\n");??
  19. }??
  20. ??
  21. int?main?()??
  22. {??
  23. ??PrintFloats?(3,3.14159,2.71828,1.41421);??
  24. ??return?0;??
  25. }</span>??

這函數PrintFloats以amount作為它的第一個參數,代表額外參數的數量,將會通過cstaarg定義的宏讀取,
并且以一種特殊的格式打印出來。



va_arg
type va_arg ( ?va_list ap, type )
獲取下一個參數
? ? 這個宏展開成了一個表達式,該表達式包含著可變參數列表中下一個參數的類型和值。
? ? 下一次調用這個宏將會展開以同樣順序傳遞給函數的下一個參數。
注意va_arg不能決定傳遞給函數的參數的實際類型,但是可以以宏type的類型作為它的類型。
同樣也需要注意va_arg不能決定此次獲取的參數是否為傳遞給該函數的參數中的最后一個。函數必須如下
來設計:參數的數量必須可以通過已經讀取的命名的或者是沒命名的參數的值來確定。

參數
ap
? ? 一個va_list類型的對象。這個參數在va_arg調用之前,必須通過調用va_start來初始化。
type
? ? 一個類型名。這個類型名就是該宏展開后的表達式的類型(例如,它的返回類型)。一個合法的適合va_arg
使用的類型表達式必須如下:當一個*號添加到它的右邊,那么它的結果表達式必須是一個合法的type類型的
指針。

返回值
以類型type的類型表達式返回下一個額外參數。


示例
[cpp] view plaincopy
  1. <span?style="font-size:16px;">/*?va_arg?example?*/??
  2. #include?<stdio.h>??
  3. #include?<stdarg.h>??
  4. ??
  5. ??
  6. int?FindMax?(?int?amount,?...)??
  7. {??
  8. ??int?i,val,greater;??
  9. ??va_list?vl;??
  10. ??va_start(vl,amount);??
  11. ??greater=va_arg(vl,int);??
  12. ??for?(i=1;i<amount;i++)??
  13. ??{??
  14. ????val=va_arg(vl,int);??
  15. ????greater=(greater>val)?greater:val;??
  16. ??}??
  17. ??va_end(vl);??
  18. ??return?greater;??
  19. }??
  20. ??
  21. ??
  22. int?main?()??
  23. {??
  24. ??int?m;??
  25. ??m=?FindMax?(7,702,422,631,834,892,104,772);??
  26. ??printf?("The?greatest?one?is:?%d\n",m);??
  27. ??return?0;??
  28. }</span>??

FindMax函數使用它的第一個參數保存將會獲取到的額外參數的數量。第一個額外的參數被獲取并且作為初始
的比較值,然后在一個循環里獲取余下的參數并且返回其中最大的一個(在這里就是892)。



va_end
void va_end( va_list ap );
? ? 執行合適的動作,使得我們可以從使用了va_list類型對象ap獲取額外參數的函數中正常返回。
? ? 無論va_start在之前的什么時候被執行,這個宏必須在函數返回之前執行。
參數
ap
? ? va_list對象,也就是之前通過va_start初始化的對象。
返回值


示例

[cpp] view plaincopy
  1. <span?style="font-size:16px;">/*?va_arg?example?*/??
  2. #include?<stdio.h>??
  3. #include?<stdarg.h>??
  4. ??
  5. void?PrintLines?(?char*?first,?...)??
  6. {??
  7. ??char*?str;??
  8. ??va_list?vl;??
  9. ??
  10. ??str=first;??
  11. ??
  12. ??va_start(vl,first);??
  13. ??
  14. ??do?{??
  15. ????printf?("%s\n",str);??
  16. ????str=va_arg(vl,char*);??
  17. ??}?while?(str!=NULL);??
  18. ??
  19. ??va_end(vl);??
  20. }??
  21. ??
  22. int?main?()??
  23. {??
  24. ??PrintLines?("First","Second","Third","Fourth",NULL);??
  25. ??return?0;??
  26. }</span>??

PrintLines函數使用了可變參數。第一個傳遞的參數是first,但是余下的參數都是在do-while循環中使用
va_arg一次獲得了,該循環在獲取的可變參數為null指針的時候結束。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452116.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452116.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452116.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Diango博客--23.單元測試:測試 blog 應用

文章目錄1. 前言2. 搭建測試環境3. 測試模型4. 測試視圖5. 測試模板標簽6. 測試輔助方法和類1. 前言 我們博客功能越來越來完善了&#xff0c;但這也帶來了一個問題&#xff0c;我們不敢輕易地修改已有功能的代碼了&#xff01; 我們怎么知道代碼修改后帶來了預期的效果&…

一般與特殊結構關系 整體與部分結構關系

一般與特殊結構關系又稱為分類結構關系&#xff0c;是“is a”關系。 例如&#xff1a;飛機與交通工具都是類&#xff0c;飛機是一種特殊的交通工具。他們之間是“is a”關系。 上層類體現一般性和共性&#xff0c;下層類體現特殊性和具體性。 用這種結構關系來描述現實世界…

簡單版:帶干擾線的圖形驗證碼生成

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1.生成工具類; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; im…

圖片格式轉換工具與方法

2019獨角獸企業重金招聘Python工程師標準>>> 使用ffmpeg進行格式轉換 1.jpg 轉 I420 ffmpeg -i 001.jpg -pix_fmt yuv420p 001_I420_fromJPG.yuv 2.png 轉 I420 ffmpeg -i 222.png -pix_fmt yuv420p 222_I420_fromPNG.yuv 3.bmp 轉 I420 ffmpeg -i xxx.bmp -pix_fmt…

Diango博客--24.單元測試:測試評論應用

文章目錄1. 前言2. 數據基類3.測試 Comment Model4. 測試視圖函數5. 測試模板標簽1. 前言 comments應用的測試和blog應用測試的套路是一樣的。 先來建立測試文件的目錄結構。首先在 comments 應用的目錄下建立一個名為 tests 的 Python 包&#xff0c;然后刪除 comments 應用…

面向對象設計使用語言選擇

面向對象設計的結果既可以用面向對象語言、也可以用非面向對象語言實現。 使用面向對象語言時&#xff0c;由于語言本身充分支持面向對象概念的實現&#xff0c;因此&#xff0c;編譯程序可以自動把面向對象概念映射到目標程序中。 使用非面向對象語言編寫面向對象程序&#xf…

結合shiro 的圖形驗證碼生成

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 在做用戶登錄功能時&#xff0c;很多時候都需要驗證碼支持&#xff0c;驗證碼的目的是為了防止機器人模擬真實用戶登錄而惡意訪問&#…

利用C語言實現計算機圖像處理的方法

1&#xff0e;圖像平移 圖像平移只是改變圖像在屏幕上的位置&#xff0c;圖像本身并不發生變化。假設原圖像區域左上角坐標為(x0, y0)&#xff0c;右下角坐標為(x1, y1)&#xff0c;將圖像分別沿x和y軸平移dx和dy&#xff0c;則新圖像的左上角坐標為(x0 &#xff0b; dx, y0 &a…

E24- please install the following Perl modules before executing ./mysql_install_db

2019獨角獸企業重金招聘Python工程師標準>>> [roott-cet7 scripts]# ./mysql_install_db --basedir/usr/local/mysql/ --datadir/app/data/ --usermysql FATAL ERROR: please install the following Perl modules before executing ./mysql_install_db: Data::Dumpe…

SpringMVC異常報406 (Not Acceptable)的解決辦法

使用SpsringMVC&#xff0c;使用restEasy調試&#xff0c;controller請求設置如下&#xff1a; Java代碼 RequestMapping(value"/list",methodRequestMethod.GET,producesMediaType.APPLICATION_JSON_VALUE) ResponseBody public List<EditTimeout> list()…

Diango博客--25.使用Coverage統計測試覆蓋率

文章目錄1. 前言2. 安裝 Coverage3. 簡單配置 Coverage4. 運行 Coverage5. 完善 Coverage 配置6. 生成 HTML 報告7. 完善單元測試1. 前言 我們完成了對 blog 應用和 comment 應用這兩個核心 app 的測試。現在我們想知道的是究竟測試效果怎么樣呢&#xff1f;測試充分嗎&#x…

面向對象語言的優點

1.一致的表達方法 從前面章節的講述中可以知道&#xff0c;面向對象開發基于不隨時間變化的、一致的表示方法。這種表示方法應該從問題域到OOA&#xff0c;從OOA到OOD&#xff0c;最后從OOD到面向對象編程(OOP)&#xff0c;始終穩定不變。 一致的表示方法&#xff1a; 既有利…

最好的英文詞典

辭典對于學外語的作用&#xff0c;怎么強調也不過分。經常接觸英語的人都知道&#xff0c;遇到生詞不可怕&#xff0c;可怕的是遇到認識的單詞&#xff0c;又不明白這句話什么意思。這個時候&#xff0c;辭典的作用就發揮出來了。 今天一位朋友問我一句英文的意思&#xff0c;…

oracle用戶創建及權限設置

權限&#xff1a; create session create table unlimited tablespace connect resource dba 例&#xff1a; #sqlplus /nolog SQL> conn / as sysdba; SQL>create user username identified by password SQL> grant dba to username; SQL> conn username/password…

Android動畫之逐幀動畫(FrameAnimation)詳解

今天我們就來學習逐幀動畫,廢話少說直接上效果圖如下: 幀動畫的實現方式有兩種&#xff1a; 一、在res/drawable文件夾下新建animation-list的XML實現幀動畫 1、首先在res/drawable文件夾下添加img00-img24共25張圖片 2、新建frame_anim.xml [html] view plaincopy <?xml v…

ajax-簡單參數方法實現陰影效果

注&#xff1a; 簡單參數 &#xff08;按照參數的數量和位置傳遞參數&#xff09; 使用時按照位置、數量傳遞 shadow.js函數//簡單參數實現方式/** slices:陰影* opacity:透明度* zIndex:層級* */jQuery.fn.shadow_simple function (slices,opacity,zIndex) { //獲取到每個…

第一二三范式的簡單理解

第一范式&#xff08;無重復的列&#xff09; 定義&#xff1a;數據庫表的每一列都是不可分割的原子數據項&#xff0c;而不能是集合&#xff0c;數組&#xff0c;記錄等非原子數據項。如果實體中的某個屬性有多個值時&#xff0c;必須拆分為不同的屬性 通俗解釋&#xff1a;一…

網絡爬蟲--1.通用爬蟲和聚焦爬蟲

文章目錄一.前言二.通用爬蟲1.工作原理2.通用爬蟲的局限性三.聚焦爬蟲一.前言 根據使用場景&#xff0c;網絡爬蟲可分為 通用爬蟲 和 聚焦爬蟲 兩種。 其中通用網絡爬蟲是捜索引擎抓取系統&#xff08;Baidu、Google、Yahoo等&#xff09;的重要組成部分。主要目的是將互聯網…

敏捷教練的工具箱

學習并不是簡簡單單的閱讀和瀏覽&#xff0c;而是一個積累的過程&#xff0c;一個通過持續的學習&#xff0c;對自己的知識體系不斷豐富、索引的過程。接下來我會從四個方面入手分享我的經驗。 高質量的信息源和高效的學習 Google是一個很好的工具&#xff0c;通過它&#x…

log4j教程

詳細的Log4j使用教程 轉載 2016年08月19日 14:44:49 5072 日志是應用軟件中不可缺少的部分&#xff0c;Apache的開源項目log4j是一個功能強大的日志組件,提供方便的日志記錄。在apache網站&#xff1a;jakarta.apache.org/log4j 可以免費下載到Log4j最新版本的軟件包。…