目录
程序的翻译环境和执行环境
编译和链接
预处理
#include <stdio.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
int main()
{
int x = 2;
int y = 3;
int z = MAX(x++, y++);
// (2++) > (3++) ❌
// x 3 y 4
// 4++
// x = 3, y = 5, z = 4
printf("x = %d\ny = %d\nz = %d\n", x, y, z);
return 0;
}
运行结果:
属性 | #define定义宏 | 函数 |
---|---|---|
代码长度 | 每次使用时,宏代码都会被插入到程序中。处理非常小的宏之外,程序的长度会大幅增长 | 函数代码只出现于一个地方;每次使用这个函数时,都会调用那个地方的同一份代码 |
执行速度 | 更快 | 存在函数的调用和返回的额外开销 |
操作符的优先级 | 宏参数的求值是在所有周围表达式的上下文环境里,除法加上括号,否则邻近操作符的优先级可能会产生不可预料的后果,所以建议宏在书写的时候多些括号 | 函数参数只在函数调用的时候求值一次,它的结果值传递给函数。表达式的求值结果更容易预测。 |
带有副作用的参数 | 参数可能被替换到宏体的多个位置,所以带有副作用的参数求值可能会产生不可预料的后果。 | 函数参数只在传参的时候求值一次,结果更容易控制 |
参数的类型 | 宏的参数与类型无关,只要对参数的操作是合法的,它就可以适用于任何参数类型 | 函数的参数与类型有关,如果参数的类型不同,就需要不同的函数,即使他们执行的任务是相同的 |
调试 | 宏是不方便调试的 | 函数是可以逐语句调试的 |
递归 | 宏是不能递归的 | 函数是可以递归的 |
#include <stdio.h>
#define MAX(x, y) ((x) > (y) ? (x) : (y))
int main()
{
int m = MAX(2, 3);
printf("%d\n", m);
return 0;
}
#include <stdio.h>
#define MAX(x, y) ((x) > (y) ? (x) : (y))
int main()
{
#undef MAX
int m = MAX(2, 3);
printf("%d\n", m);
return 0;
}
#include <stdio.h>
int main()
{
int arr[ARRAY_SIZE];// 可以在编译的过程中使用命令行参数来给数组的大小赋值
for (int i = 0; i < ARRAY_SIZE; i++) {
arr[i] = i;
}
for (int i = 0; i < ARRAY_SIZE; i++) {
printf("%d ", arr[i]);
}
return 0;
}
#include <stdio.h>
#define M 0
int main()
{
int i = 0;
int n = 10;
for (i = 0; i < 10; i++) {
#if M
printf("%d ", i);
#endif
printf("1 ");
}
return 0;
}
#include <stdio.h>
#define M 2
int main()
{
int i = 0;
int n = 10;
for (i = 0; i < 10; i++) {
#if M
printf("%d ", i);
#endif
printf("1 ");
}
return 0;
}
#include <stdio.h>
#define M 150
int main()
{
#if M < 100
printf("less\n");
#elif M == 100
printf("equal\n");
#elif M > 100 && M < 200
printf("middle\n");
#else
printf("more\n");
#endif
return 0;
}
#include <stdio.h>
#define M 0
int main()
{
#ifdef M
printf("Mdefine1\n");
#endif
#if defined(M)
printf("Mdefine2\n");
#endif
#ifndef M
printf("Mnodef1\n");
#endif
#if !defined(M)
printf("Mnodef2\n");
#endif
return 0;
}
#include <stdio.h>
int main()
{
#ifdef M
printf("Mdefine1\n");
#endif
#if defined(M)
printf("Mdefine2\n");
#endif
#ifndef M
printf("Mnodef1\n");
#endif
#if !defined(M)
printf("Mnodef2\n");
#endif
return 0;
}