在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言可變參數的使用詳解

硬件攻城獅 ? 來源:硬件攻城獅 ? 2023-03-08 09:47 ? 次閱讀

一、可變參數表介紹

c/c++語言具備一個不同于其他編程語言的的特性,即支持可變參數

例如C庫中的printf,scanf等函數,都支持輸入數量不定的參數。例如:

printf("helloworld");////

printf函數原型為 int printf(const char *format, …);

從printf的原型來看,其除了接受一個固定參數format以外,后面的參數使用來表示。

在c/c++語言中,表示可以接受不定數量的參數。

二、可變參數表用法

在標準C/C++中,頭文件中定義了如下三個宏:

voidva_start(va_listarg_ptr,prev_param);/*ANSIversion*/
typeva_arg(va_listarg_ptr,type);
voidva_end(va_listarg_ptr);

va 就是variable argument(可變參數)的意思

arg_ptr 是指向可變參數表的指針

prev_param 則指可變參數表的前一個固定參數

type 為可變參數的類型

va_list 也是一個宏

其定義為typedef char * va_list 實質上是一char 型指針。
char 型指針的特點是++、--操作對其作用的結果是增1 和減1(因為sizeof(char)為1)。
與之不同的是int 等其它類型指針的++、--操作對其作用的結果是增sizeof(type)或減sizeof(type),而且sizeof(type)大于1。

通過使用va_start宏我們可以取得可變參數表的首指針,這個宏的定義為:

#defineva_start(ap,v)(ap=(va_list)&v+_INTSIZEOF(v))

其作用為將最后那個固定參數的地址加上可變參數對其的偏移后賦值給ap,這樣ap就是可變參數表的首地址。

_INTSIZEOF 宏定義為:

#define_INTSIZEOF(n)((sizeof(n)+sizeof(int)–1)&~(sizeof(int)–1))

宏定義va_arg原型為:

#defineva_arg(list,mode)((mode*)(list=
(char*)((((int)list+(__builtin_alignof(mode)<=4?3:7))?&
(__builtin_alignof(mode)<=4?-4:-8))+sizeof(mode))))[-1]

其作用為指取出當前arg_ptr 所指的可變參數并將ap 指針指向下一可變參數。

va_end宏定義用來結束可變參數的獲取,定義為:

#defineva_end(list)

va_end ( list )實際上被定義為空,沒有任何真實對應的代碼,用于代碼對稱,與va_start對應;

可能發揮代碼的“自注釋”作用。所謂代碼的“自注釋”,指的是代碼能自己注釋自己。

三、可變參數表的簡單使用

#include
#include
#include

/**
*@brief求n個數中的最大值
*@details
*@param[in]num整數個數
*@param[out]...整數
*@retval最大整數
*@par
*/
intmax(intnum,...){
intm=-0x7FFFFFFF;/*32系統中最小的整數*/
va_listap;
va_start(ap,num);
for(inti=0;im){
m=t;
}
}
va_end(ap);
returnm;
}

intmain(intargc,char*argv[]){
intn=max(5,5,6,3,8,5);/*求5個整數中的最大值*/
cout<

max(int num, …)中首先定義了可變參數表指針ap,而后通過va_start ( ap, num )取得了參數表首地址(賦給了ap),其后的for 循環則用來遍歷可變參數表。

max函數相比于printf簡單了許多,其原因如下:

max函數可變參數表的長度是已知的,通過num參數傳入;

max函數可變參數表中參數的類型是已知的,都為int型;

printf 函數可變參數的個數不能輕易的得到,而可變參數的類 型也不是固定的,需由格式字符串進行識別(由%f、%d、%s 等確定)。

四、運行機制

匯編是研究語法深層特性的終極良策,首先查看main函數中調用max函數時的反匯編:

1.004010C8push5
2.004010CApush8
3.004010CCpush3
4.004010CEpush6
5.004010D0push5
6.004010D2push5
7.004010D4call@ILT+5(max)(0040100a)

第一步:將參數從右向左入棧(第1~6行)

第二步:調用call 指令進行跳轉(第7行)

這兩步包含了深刻的含義,它說明C/C++默認的調用方式為由調用者管理參數入棧的操作,且入棧的順序為從右至左,這種調用方式稱為_cdecl調用。

x86系統的入棧方向為從高地址到低地址,故第1至n個參數被放在了地址遞增的堆棧內。在被調用函數內部,讀取這些堆棧的內容就可獲得各個參數的值,讓我們反匯編到max函數的內部。

intmax(intnum,...){
1.00401020pushebp
2.00401021movebp,esp
3.00401023subesp,50h
4.00401026pushebx
5.00401027pushesi
6.00401028pushedi
7.00401029leaedi,[ebp-50h]
8.0040102Cmovecx,14h
9.00401031moveax,0CCCCCCCCh
10.00401036repstosdwordptr[edi]
va_listap;
intm=-0x7FFFFFFF;/*32系統中最小的整數*/
11.00401038movdwordptr[ebp-8],80000001h
va_start(ap,num);
12.0040103Fleaeax,[ebp+0Ch]
13.00401042movdwordptr[ebp-4],eax
for(inti=0;im)
28.00401071moveax,dwordptr[t]
29.00401074cmpeax,dwordptr[ebp-8]
30.00401077jlemax+5Fh(0040107f)
m=t;
31.00401079movecx,dwordptr[t]
32.0040107Cmovdwordptr[ebp-8],ecx
}
33.0040107Fjmpmax+2Eh(0040104e)
va_end(ap);
34.00401081movdwordptr[ebp-4],0
returnm;
35.00401088moveax,dwordptr[ebp-8]
}
36.0040108Bpopedi
37.0040108Cpopesi
38.0040108Dpopebx
39.0040108Emovesp,ebp
40.00401090popebp
41.00401091ret

第1~10行進行執行函數內代碼的準備工作,保存現場;

第2行對堆棧進行移動;

第3行則意味著max函數為其內部局部變量準備的堆棧空間為50h字節;

第11行表示把變量n 的內存空間安排在了函數內部局部棧底減8的位置(占用4個字節);

第12~13行非常關鍵,對應著va_start ( ap, num),這兩行將第一個可變參數的地址賦值給了指針ap;

從第12行可以看出num 的地址為ebp+0Ch;

從第13行可以看出ap 被分配在函數內部局部棧底減4 的位置上(占用4 個字節);

第22~27行最為關鍵,對應著va_arg (ap, int);

第22~24行的作用為將ap 指向下一可變參數(可變參數的地址間隔為4 個字節,從add eax,4 可以看出);

第25~27行則取當前可變參數的值賦給變量t。這段反匯編很奇怪,它先移動可變參數指針,再在賦值指令里面回過頭來取先前的參數值賦給t(從mov edx,dword ptr [ecx-4]語句可以看出);

第36~41行恢復現場和堆棧地址,執行函數返回操作。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7604

    瀏覽量

    136826
  • 編程語言
    +關注

    關注

    10

    文章

    1945

    瀏覽量

    34736
  • 函數
    +關注

    關注

    3

    文章

    4331

    瀏覽量

    62618
  • C++
    C++
    +關注

    關注

    22

    文章

    2108

    瀏覽量

    73651
  • 可變參數
    +關注

    關注

    0

    文章

    2

    瀏覽量

    4818

原文標題:C語言可變參數的使用詳解

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    C語言可變形參是什么

    ??C語言允許定義參數數量可變的函數,這稱為可變參數函數(variadic function)。
    的頭像 發表于 08-18 21:40 ?1332次閱讀

    可變參數函數的實現原理

    ,或者其它方式。在C語言標準頭文件stdarg.h里面已經為可變函數定義了幾個宏,使用這些宏也可以實現可變參數函數,原理都一樣, 細節不再介
    發表于 10-21 22:18

    C語言內存管理詳解

    C語言內存管理詳解,很不錯的一份資料.
    發表于 08-06 23:14

    C語言——可變參數問題.

    ;The value is %d!\n", value);  這種可變參數可以說是C語言一個比較難理解的部分,這里會由幾個問題引發一些對它的分析。   注意:在
    發表于 04-20 15:17

    C語言可變參數的定義

    C語言可變參數的定義。//可變參數用...來表示void TRACE(char *forma
    發表于 07-14 07:43

    怎么設計c語言可變參數函數?

    怎么設計c語言可變參數函數
    發表于 10-27 07:10

    C++ 語言命令詳解(第二版)

    電子發燒友網站提供《C++ 語言命令詳解(第二版).txt》資料免費下載
    發表于 07-28 13:06 ?0次下載

    C語言詳解_ifdef等宏及妙用

    C語言詳解_ifdef等宏及妙用的教程
    發表于 11-16 19:03 ?0次下載

    徹底搞定C語言指針詳解完整版

    徹底搞定C語言指針詳解完整版。
    發表于 05-10 17:04 ?0次下載

    ARM_C語言程序設計詳解

    ARM_C語言程序設計詳解
    發表于 10-27 15:39 ?32次下載
    ARM_<b class='flag-5'>C</b><b class='flag-5'>語言</b>程序設計<b class='flag-5'>詳解</b>

    C語言的精髓——指針詳解

    C語言的精髓——指針詳解
    發表于 11-30 14:43 ?17次下載

    單片機C語言和匯編語言混合編程實例詳解

    單片機C語言和匯編語言混合編程實例詳解
    發表于 08-16 09:50 ?225次下載

    C語言-函數的可變形參(不定形參)

    這篇文章介紹C語言函數的不定參數可變參數 形參,實現printf一樣的傳參效果。
    的頭像 發表于 08-14 09:58 ?2672次閱讀

    c語言參數的宏定義

    c語言參數的宏定義? C語言宏定義是一種宏替換機制,它可以將一個標識符替換為一個代碼片段。宏定義通常在程序中用來方便地進行常量定義或函數模
    的頭像 發表于 09-04 17:45 ?2416次閱讀

    C語言中的可變參數介紹

    C 語言為這種情況提供了一個解決方案,它允許您定義一個函數,能根據具體的需求接受可變數量的參數
    發表于 02-28 14:00 ?309次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>中的<b class='flag-5'>可變</b><b class='flag-5'>參數</b>介紹
    主站蜘蛛池模板: 日本人的xxxxxxxxx69| 亚洲啊v| 丁香综合网| 日本68xxxxxxxxx老师| 曰本三级香港三级人妇99视频| 五月激情五月婷婷| 欧美成人生活片| 丁香花小说| 欧美午夜免费观看福利片| 欧美一区二区三区激情啪啪| 久久久久国产一级毛片高清板| 亚洲jizzjizz中文在线播放| 韩日成人| 欧美在线bdsm调教一区| 黄网站在线观看视频| 色多多视频成人影院| 很色视频| 国产精品超清大白屁股| 污污视频在线免费看| 四虎永久地址4hu紧急入口| 开心激情婷婷| 天天爽夜夜爽夜夜爽| 美国人与性xxxxxxx| 亚洲日韩色综合视频| 久久青草国产精品一区| 天天做夜夜操| 年下系列高h文| 日本特级黄色大片| 777成了人乱视频| 亚洲国产七七久久桃花| 亚洲免费视频在线观看| 成年黄网站免费大全毛片| 国产真实乱在线更新| 国产精品第9页| 免费一级欧美片在线观看 | 九九精品久久久久久噜噜| 小雪被老外黑人撑破了视频| 美国69bj| 欧美成人性动漫在线观看| 国产高清亚洲| 日本三级免费网站|