色偷偷偷亚洲综合网另类,亚洲欧美另类在线观看,欧美午夜激情在线,久久久精品一区

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > 不定參函數

不定參函數 時間:2018-09-21      來源:未知

有很多同學對我們經常使用的函數printf和scanf都不以為然,其實這兩個函數在c語言當中還是比較典型的。一般我們編程的時候,函數中形式參數的數目通常是確定的,在調用時要依次給出與形式參數對應的實際參數。但在某些情況下我們希望函數的參數個數可以根據需要確定,因此c語言引入可變參數函數。典型的可變參數函數的例子有printf()、scanf()。

下面我們就說一下這些函數的實現。

這些不定參數函數在c語言中是通過堆棧的方式實現的,這樣看來理論上好像參數的個數是沒有限制的實際上由于內存或者棧的大小的限制,實際上參數的個數是有上限的,只是這個上限我們一般情況下不會達到。如果達到了也會出現錯誤。

在c語言中,不定參函數的具體實現主要通過c語言定義的幾個函數宏來完成,具體內部空間如何分配,如何調用均在其中,這也為我們自己完成一些不定餐函數提供了便利條件。下面介紹下這些函數宏。

VA_LIST 是在C語言中解決變參問題的一組宏,所在頭文件:#include <stdarg.h>

INTSIZEOF 宏,獲取類型占用的空間長度,小占用長度為int的整數倍:

#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

VA_START宏,獲取可變參數列表的第一個參數的地址(ap是類型為va_list的指針,v是可變參數左邊的參數):

#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )

VA_ARG宏,獲取可變參數的當前參數,返回指定類型并將指針指向下一參數(t參數描述了當前參數的類型):

#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

VA_END宏,清空va_list可變參數列表:

#define va_end(ap) ( ap = (va_list)0 )

具體用法:

(1)首先在函數里定義一具VA_LIST型的變量,這個變量是指向參數的指針;

(2)然后用VA_START宏初始化剛定義的VA_LIST變量;

(3)然后用VA_ARG返回可變的參數,VA_ARG的第二個參數是你要返回的參數的類型(如果函數有多個可變參數的,依次調用VA_ARG獲取各個參數);

(4)后用VA_END宏結束可變參數的獲取。

Ok下面舉個例子來說明下:

void arg_test(int i, ...);

int main(int argc,char *argv[])

{

int int_size = _INTSIZEOF(int);

printf("int_size=%d\n", int_size);

arg_test(0, 4);

//arg_cnt(4,1,2,3,4);

return 0;

}

void arg_test(int i, ...)

{

int j=0;

va_list arg_ptr;

va_start(arg_ptr, i);

printf("&i = %p\n", &i);//打印參數i在堆棧中的地址

printf("arg_ptr = %p\n", arg_ptr);//打印va_start之后arg_ptr地址

/*這時arg_ptr應該比參數i的地址高sizeof(int)個字節,即指向下一個參數的地址*/

j=*((int *)arg_ptr);

printf("%d %d\n", i, j);

j=va_arg(arg_ptr, int);

printf("arg_ptr = %p\n", arg_ptr);//打印va_arg后arg_ptr的地址

/*這時arg_ptr應該比參數i的地址高sizeof(int)個字節,即指向下一個參數的地址,如果已經是后一個參數,arg_ptr會為NULL*/

va_end(arg_ptr);

printf("%d %d\n", i, j);

}

說明:

int int_size = _INTSIZEOF(int);得到int類型所占字節數

va_start(arg_ptr, i); 得到第一個可變參數地址

根據定義(va_list)&v得到起始參數的地址, 再加上_INTSIZEOF(v) ,就是其實參數下一個參數的地址,即第一個可變參數地址。

j=va_arg(arg_ptr, int); 得到第一個可變參數的值,并且arg_ptr指針上移一個_INTSIZEOF(int),即指向下一個可變參數的地址。

va_end(arg_ptr);置空arg_ptr,即arg_ptr=(void *)0;

在這里還要說一下,不定參數在c語言中的函數原型寫法參數部分是“...”三個點。

后附上一個我們自己寫的簡單的printf的代碼:

#include <stdarg.h>

void my_printf(const char* fmt, ... )

{

va_list ap;

va_start(ap,fmt); /* 用后一個具有參數的類型的參數去初始化ap */

for (;*fmt;++fmt)

{

/* 如果不是控制字符 */

if (*fmt!='%')

{

putchar(*fmt); /* 直接輸出 */

continue;

}

/* 如果是控制字符,查看下一字符 */

++fmt;

if ('\0'==*fmt) /* 如果是結束符 */

{

assert(0); /* 這是一個錯誤 */

break;

}

switch (*fmt)

{

case '%': /* 連續2個'%'輸出1個'%' */

putchar('%');

break;

case 'd': /* 按照int輸出 */

{

/* 下一個參數是int,取出 */

int i = va_arg(ap,int);

printf("%d",i);

}

break;

case 'c': /* 按照字符輸出 */

{

/** 但是,下一個參數是char嗎*/

/* 可以這樣取出嗎? */

char c = va_arg(ap,char);

printf("%c",c);

}

break;

}

}

}

va_end(ap); /* 釋放ap—— 必須! 見相關鏈接*/

}

看完后,你是不是自己也想試一下實現一個不定參函數呢。

上一篇:函數tmpnam和tmpfile的用法

下一篇:Coretex_M0工程創建

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5,京公海網安備11010802025203號

回到頂部

色偷偷偷亚洲综合网另类,亚洲欧美另类在线观看,欧美午夜激情在线,久久久精品一区
主站蜘蛛池模板: 久久久精品视频成人| 欧美激情在线狂野欧美精品| 毛片精品免费在线观看| 国产精品久久久久久久久久三级| 国模吧一区二区三区| 亚洲天堂av高清| 国产精品入口日韩视频大尺度| 国产精品扒开腿做爽爽爽男男| 国产精品99一区| 久久久久久97| 国产精品91一区| 亚洲free性xxxx护士白浆| 性欧美亚洲xxxx乳在线观看| www.亚洲成人| 亚洲女人天堂av| 91伊人影院在线播放| 国产精品成人v| 亚洲在线观看视频网站| 国产午夜精品视频免费不卡69堂| 精品国产欧美成人夜夜嗨| 国产亚洲a∨片在线观看| 久精品免费视频| 久久91精品国产91久久跳| 日韩av在线直播| 亚洲国产成人在线视频| 成人精品久久一区二区三区| 国产成人精品a视频一区www| 日韩精品在线影院| 亚洲女同精品视频| 色综合视频一区中文字幕| 欧美成人精品激情在线观看| 7777精品视频| 国产精品夜色7777狼人| 国产精品美女www爽爽爽视频| 亚洲精品视频中文字幕| 久久久久国产精品www| 亚洲国产天堂网精品网站| 亚洲精品狠狠操| 欧美国产日本在线| 欧美亚洲视频一区二区| 91精品国产99|