1.宏
概述
宏可以定义一个宏常量,或者定义一个宏函数。其实本质都是字符替换。
代码预编译的时候会展开,所以它的运行速度比函数快。适合小而常用的功能。
用例
参数和语句都要放在()中
#define SUM(a, b)((a) + (b)) //宏实现两个数的加法
#define MIN(a, b)(((a) < (b)) ? (a) : (b)) // 宏实现两个数中比最小的
特点:
1.宏比函数执行速度快。(优点)
2.宏函数对参数的类型没有限制。比如例子中的函数,参数可以是int, double, float, char。(优点)
3.但是正因为对参数没有限制,以及先展开后计算,所以容易引发二义性。(缺点)
2.函数
概述
函数的编译和调用过程相对复杂。
主要考察参数压栈的过程。
函数调用参数压栈
顺序:从右向左。
原因:函数调用的约定,如果有参数个数不确定的函数例如int printf(char *format, ...),通常参数个数都是由第一个参数决定的。从右向左压栈可以保证第一个取出来,然后根据它取不确定的参数。
试想一下如果从左向右的话,就会陷入死循环。
顺便学习一个C语言泛型编程的例子,自己实现一个printf函数,主干代码如下:
int my_printf(const char *format, ...)
{
assert(format != NULL);
int count = 0;
va_list var;
va_start(var, format);
for(int i = 0; format[i] != '\0'; i++)
{
if(format[i] == '%')
{
switch(format[++i])
{
case 'c':
c = (char)va_arg(var, int);
putchar(c);
count++;
break;
case 'd':
...
break;
...
default:
putchar(format[i]);
count++;
break;
}
}else if(format[i] == '\\')
{
switch(format[++i])
{
case 'n'
...
}
}
...
}
va_end(var);
return count;
}