色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

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

不定參函數 時間: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號

回到頂部

主站蜘蛛池模板: 千金被调教室跪趴SM | 欧美老人巨大xxxx做受视频 | 小荡货你夹的老师好紧 | 亚洲成av人的天堂在线观看 | 伊人久久无码中文字幕 | 国产精品久久久久无码AV色戒 | 狠狠久久噜噜熟女 | 亚洲精品成人网线在线播放va | 久久韩| 久久AV老司机精品网站导航 | wwwwwww黄 | 女教师大荫蒂毛茸茸 | 无码精品久久久天天影视 | 国产人澡人澡澡澡人视频 | 国模大胆无码私拍啪啪AV | 欧美日韩一区二区三区免费 | 欧美白丰满老太aaa片 | 亚洲人成网站在线观看播放 | 亚洲乱码日产精品BD在线观看 | 亚洲夜夜欢a∨一区二区三区 | 国产极品熟女沙发内射AV | 各处沟厕大尺度偷拍女厕嘘嘘 | 国精产品W灬源码1688伊在线 | 给我免费播放片高清在线观看视频 | 久久久久久综合网天天 | 国产又滑又嫩又白 | 男男暴菊gay无套网站 | 红尘影院手机在线观看 | 久久WWW免费人成一看片 | 国产中年熟女高潮大集合 | 1000部啪啪未满十八勿入 | 美女黄网站18禁免费看胸罩 | 噜噜噜在线观看免费视频 | 中文字幕日韩高清在线 | 欧美一区二区三区国产 | 亚洲中文字慕日产2021 | 青青草免费在线视频 | 国产免费丝袜调教视频 | 小蝌蚪视频色版 | 亚洲av无码一区二区三区牲色 | 国产精品天干天干 |