C语言面试题---函数(二)
2017-12-25 09:55
169 查看
版本声明:本文转载于公众号TeachPlus
C语言面试题----函数(二)
c语言中,跟函数相关的考题,偶尔还会出现与变长参数相关的问题。
在C语言编程中有时会遇到一些参数个数可变的函数,例如 printf(),scanf() 函数,
查看man手册时其函数原型为:
int printf(const char* format,…); int scanf(const char *format,…);
它除了有一个参数format固定以外,后面跟着的参数的个数和类型是可变的(用三个点“…”做参数
占位符),实际调用时可以有以下的形式:
printf(“%d”,i); printf(“%d,%c”,i,j);
这就是所谓参数可变的函数。
C语言用 va_start 等宏来处理这些可变参数。这些宏看起来很复杂,其实原理挺简单,就是根据参数入栈的特点从最靠近第一个可变参数的固定参数开始,依次获取每个可变参数的地址。
在标准C语言中定义了一个头文件 <stdarg.h> 专门用来对付可变参数列表,它
包含了一组宏,和一个 va_list 的 typedef 声明。来看一个例子:
# include <stdio.h> # include <stdarg.h> # include <stdlib.h> void test( int num ,...); int main() { test(5,3,5,2,0,3); return 0; } void test( int num,...) { va_list ap; va_start(ap,num); int i = 0; for(i = 0 ; i < num; i++) { printf("%d\n",va_arg(ap, int)); sleep(1); } va_end(ap); }
函数输出为:
35
2
0
3
在本例中,首先包含了 <stdarg.h> 头文件,处理不定长参数的宏全部定义在这里面,
所以用到可变参数的程序应该包含这个头文件.
然后声明了不定长参数函数 test() ,这里需要注意的是,所以为的不定长参数列列表,
只是指 ... 代表的部分,前面的 int num 不属于不定长参数列表。
然后在函数中,首先定义了 va_list 类型的 ap ,这个变量是指向参数地址的指针.
因为得到参数的地址之后,再结合参数的类型,才能得到参数的值。
再然后用 va_start 宏初始化上一步中定义的变量 ap ,这个宏的第二个参数是可变
参数列表的前一个参数,也就是最后一个固定参数。在本例中就是 int num 。
然后依次用 va_arg 宏使 ap 返回可变参数的地址,得到这个地址之后,结合参数的类型,
就可以得到参数的值。然后进行输出。
可变参数用到以下宏函数:
<1>原型: void va_start(va_list arg_ptr,prev_param);功能:以固定参数的地址为起点确定变参的内存起始地址,获取第一个参数的首地址
返回值:无
<2>原型: va_list 类型的变量, va_list ap ,这个变量是指向参数地址的指针,
因为得到参数的地址之后,再结合参数的类型,才能得到参数的值。
<3>原型: type va_arg(va_list arg_ptr,type);
功能:获取下一个参数的地址
返回值:根据传入参数类型决定返回值类型
<4>原型: void va_end(va_list arg_ptr);
功能:将arg_ptr指针置0
返回值:无
最后一道题目巩固一下,利用变长参数输出不定长字符串
答案:
# include <stdio.h>
# include <stdarg.h> void PrintLines( char *first,...) { char *str; va_list v1; str = first; va_start(v1,first); do { printf("%s\n",str); str=va_arg(v1, char*); }while (str != NULL ); va_end(v1); } int main( int argc, char* argv[]) { PrintLines("First","Second","Third","Fourth",NULL); return 0; }
相关文章推荐
- 【面试题】C语言:使用函数实现两个数的交换
- [笔记]一道C语言面试题:实现 itoa() 函数
- 【面试题】C语言:模拟实现内存放置函数memset()
- 百度面试题——用C语言实现函数void * memmove(void *dest,const void *src,size_t n)
- 百度面试题——用C语言实现函数void * memmove(void *dest,const void *src,size_t n)
- 【C语言】【笔试题】【面试题】实现一个函数,可以左旋字符串中的k个字符
- 【C语言】【面试题】【笔试题】编写一个函数实现n^k,使用递归实现
- 【C语言】【笔试题】【面试题】实现一个函数,可以左旋字符串中的k个字符
- 12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
- 【C语言】【笔试题】【面试题】实现一个函数,可以左旋字符串中的k个字符
- 【C语言】【面试题】【笔试题】编写一个函数实现n^k,使用递归实现
- 12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
- C语言面试题收集(函数调用、指针等)
- 【面试题】C语言:实现一个函数,判断一个数是不是素数。
- 12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!
- 【面试题】C语言:模拟实现内存放置函数memset()
- 有助于理解C语言一些函数的面试题
- C语言的fork函数在Linux中的进程操作及相关面试题讲解
- 【C语言】【面试题】【笔试题】.字符串替换空格:请实现一个函数,把字符串中的每个空格替换成“%20”。
- 12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!