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;
}
C语言中可以定义参数可变的函数
参数可变函数的实现依赖于stdarg.h头文件
va_list变量与va_start, va_end和va_arg配合使用能够
访问参数值
可变参数的限制
可变参数必须从头到尾按照顺序逐个访问
参数列表中至少要存在一个确定的命名参数
可变参数宏无法判断实际存在的参数的数量
可变参数宏无法判断参数的实际类型
警告:
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;
}
函数VS 宏
宏是由预处理直接替换展开的,编译器不知道宏的存在
函数是由编译器直接编译的实体,调用行为由编译器决定
多次使用宏会导致程序代码量增加
函数是跳转执行的,因此代码量不会增加
宏的效率比函数要高,因为是直接展开,无调用开销
函数调用时会创建活动记录,效率不如宏
宏的优点和缺点
宏的效率比函数稍高,但是其副作用巨大,容易
出错
#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);
小结
宏和函数并不是竞争对手
宏能够接受任何类型的参数,效率高,易出错
函数的参数必须是固定类型,效率稍低,不易出错
宏可以实现函数不能实现的功能