色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號

回到頂部

主站蜘蛛池模板: 玩护士睡老师勾搭女下属 | 又硬又水多又坚少妇18P | 日韩性做爰免费A片AA片 | 神马午夜一区二区 | 真实国产乱子伦精品视频 | 婚外情欲三级无删减版 | 调教凌虐妻妾奴在线播放 | 久久亚洲国产成人精品无码区 | 国产精品多人P群无码 | 19禁无遮挡啪啪无码网站 | 亚洲VA在线VA天堂XXXX中文 | 老师你下面太紧进不去动态图 | 中文字幕 亚洲精品 第1页 | 日本少妇毛茸茸高潮 | 中国护士xxxxhd少妇 | 亚洲日韩av一区二区三区中文 | 久久97超碰色中文字幕蜜芽 | 九色com | 久久精品女人天堂AV | 国产产无码乱码精品久久鸭 | chinesegayxnxx雷爷精品系列 | YY111111少妇影院免费观看 | 少妇人妻av毛片在线看 | www.日本一区二区 | 国产在线观看无码免费视频 | 中文字幕无码久久一区 | 黑人大战中国av女叫惨了 | 日韩东京热无码AV一区 | 国产精品久久久久9999县 | 蝴蝶谷最新网址 | 国产高跟丝袜脚交视频 | 欧美日韩一区精品视频一区二区 | 在线看a视频 | 久久精品国产亚洲AV无码麻豆 | 狠狠色噜噜狠狠狠狠888奇米 | 成人黄网站片免费视频软件 | 无码一区二区三区av免费 | 人妻丰满熟妞AV无码区 | 欧美人妻少妇精品久久黑人 | 国产精品人妻熟女毛片av久久 | 国产精品夜夜嗨 |