1. 问 如何编写一个可以计算n个数平均值的函数?
答;
#include <stdio.h> float func(int array[], int size) { int i = 0; float avr = 0; for(i=0; i<size; i++) { avr += array[i]; } return avr / size; } int main() { int array[] = {1, 2, 3, 4, 5}; printf("%f\n", func(array, 5)); return 0; }
#include <stdio.h> #include <stdarg.h> float average(int n, ...) { va_list args; int i = 0; float sum = 0; va_start(args, n); for(i=0; i<n; i++) { sum += va_arg(args, int); } va_end(args); return sum / n; } int main() { printf("%f\n", average(5, 1, 2, 3, 4, 5)); printf("%f\n", average(4, 1, 2, 3, 4)); return 0; }
可变参数的限制
可变参数必须从头到尾按照顺序逐个访问
参数列表中至少要存在一个确定的命名参数
可变参数宏无法判断实际存在的参数的数量
可变参数宏无法判断参数的实际类型
警告:
va_arg中如果指定了错误的类型,那
么结果是不可预测的。
小结
可变参数是C语言提供的一种函数设计技巧
可变参数的函数提供了一种更方便的函数调用方式
可变参数必须顺序的访问
无法直接访问可变参数列表中间的参数值
李逵VS 李鬼
#include <stdio.h> #define RESET(p, len) while( len > 0) ((char*)p)[--len] = 0 void reset(void* p, int len) { while( len > 0 ) { ((char*)p)[--len] = 0; } } int main() { int array[] = {1, 2, 3, 4, 5}; int len = sizeof(array); reset(array, len); RESET(array, len); return 0; }
宏的优点和缺点
宏的效率比函数稍高,但是其副作用巨大,容易
出错
#include <stdio.h> #define ADD(a, b) a + b #define MUL(a, b) a * b #define _MIN_(a, b) ((a) < (b) ? (a) : (b)) int main() { int i = 1; int j = 10; printf("%d\n", MUL(ADD(1, 2), ADD(3, 4))); printf("%d\n", _MIN_(i++, j)); return 0; }
1+2*3+4
((i++)<(j)?(i++);(j))
函数优点和缺点
函数存在实参到形参的传递,因此无任何副作用
,但是函数需要建立活动对象,效率受影响
#include <stdio.h> int add(int a, int b) { return a + b; } int mul(int a, int b) { return a * b; } int _min_(int a, int b) { return a < b ? a : b; } int main() { int i = 1; int j = 10; printf("%d\n", mul(add(1, 2), add(3, 4))); printf("%d\n", _min_(i++, j)); return 0; }
宏无可替代的优势
宏参数可以是任何C语言实体
宏编写的_MIN_参数类型可以是int, float等等
宏的参数可以是类型名
#define MALLOC(type , n) (tyde * malloc( n* sizeof(type))
int *p = MALLOC(int,5);
小结
宏和函数并不是竞争对手
宏能够接受任何类型的参数,效率高,易出错
函数的参数必须是固定类型,效率稍低,不易出错
宏可以实现函数不能实现的功能