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

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

不定參函數 時間: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片在线| 日韩最新免费不卡| 亚洲成在人线av| 亚洲电影免费观看高清完整版| 91精品美女在线| 亚洲电影免费在线观看| 精品亚洲永久免费精品 | 日韩在线中文字幕| 色吧影院999| 欧美色视频日本高清在线观看| 国模精品视频一区二区三区| 91成人福利在线| 国产欧美一区二区| 亚洲美女av在线播放| 中文字幕在线国产精品| 日韩欧美高清视频| 国产精品对白刺激| 亚洲欧美综合区自拍另类| 久久久国产精品亚洲一区| 久久久久成人网| 国产欧美精品一区二区三区-老狼| 日韩高清免费在线| 久久91精品国产91久久久| 日韩av免费在线看| 亚洲精品一区二区网址| 成年无码av片在线| 国产精品久久视频| 最近2019中文字幕一页二页 | 日韩欧美第一页| 国产在线拍揄自揄视频不卡99 | 国产精品一区二区三区在线播放| 国产偷国产偷亚洲清高网站| 久久91亚洲精品中文字幕| 欧洲永久精品大片ww免费漫画| 亚洲精品福利免费在线观看| 久久成人精品电影| 欧美诱惑福利视频| 亚洲韩国日本中文字幕| 久久777国产线看观看精品| 成人中心免费视频| 久久国产精品久久国产精品|