专题6-2,可变参数列表与宏分析(国嵌C语言视频)

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);

小结
宏和函数并不是竞争对手
宏能够接受任何类型的参数,效率高,易出错
函数的参数必须是固定类型,效率稍低,不易出错
宏可以实现函数不能实现的功能





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值