我们的代码写完后称为源代码,源代码一般都要经过由编译器和链接器组成的翻译环境中,翻译成二进制的指令(机器指令),再进入执行环境一步步执行代码。
其中,在编译过程中,符号汇总是指将所有.c文件的函数名汇总在一起;在汇编过程中的形成符号表是指,将所有.c文件中的函数都给一个地址,其中,在主函数中的函数如果只有声明时,会给一个无效的地址,例如空地址,但是它的有效地址可能在另一个.c文件中定义了;然后会在链接器中的符号表的合并和重定位中,取它的有效地址;在链接器中的合并段表中,将所有的.o文件(目标文件)一一对应的匹配合并,目标文件是有格式的,它会按照格式一一对应的合并;
例如:
#define MAX 1000
int main()
{
printf("%d\n", MAX);
int arr[MAX];
return 0;
}
#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏或定义宏。
例如:
#define SQUARE(x) ((x)*(x)) //注意SQUARE的后面不能接空格,要直接用括号括住参数
int main()
{
printf("%d\n", SQUARE(1+7));
return 0;
}
在使用#define定义宏时,要尽量多的去使用括号,避免在替换过程中符号的优先级影响计算的结果;
在程序中扩展#define定义符号和宏时,需要涉及几个步骤。
下面这个程序,首先替换#define定义的宏DOUBLE(x) ,再进行其他计算;
#define DOUBLE(x) ((x)+(x))
int main()
{
int a = 10*DOUBLE(4);
printf("%d\n", a);
return 0;
}
使用 # ,把一个宏参数变成对应的字符串
// \是续行符,把下一行的代码续上上一行,实际上还是一行代码
#define print_format(num, format) \
printf("the value of "#num" is "format, num)
int main()
{
int a = 10;
print_format(a, "%d\n");//the value of a is 10
//printf("the value of a is %d\n", a);
int b = 20;
print_format(b, "%d\n");//the value of b is 20
//printf("the value of b is %d\n", b);
float f = 3.14f;
print_format(f, "%f\n");//the value of f is 3.140000
//printf("the value of f is %f\n", f);
return 0;
}
##可以把位于它两边的符号合成一个符号。它允许宏定义从分离的文本片段创建标识符.
int Class109 = 2022;
//将参数Class和109合成一个
#define CAT(x,y) x##y
//Class109
int main()
{
printf("%d\n", CAT(Class, 109)); //2022
return 0;
}
宏通常被应用于执行简单的运算; 比如在两个数中找出较大的一个:#define MAX(a, b) ((a)>(b)?(a):(b))
这里不用函数的原因:
宏的缺点: 当然和函数相比宏也有劣势的地方:
但是宏有时候可以做函数做不到的事情。比如:宏的参数可以出现类型,但是函数做不到;eg:
#define MALLOC(num,type) (type*)malloc(num * sizeof(type))
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
assert(p);
//实现一个宏表示malloc
int* p2 = MALLOC(10, int);
assert(p2);
return 0;
}
#if 遇到 #endif 就会结束
#if defined(symbol) #ifdef symbol 只要symbol被定义,这个条件就为真,symbol为0也为真;
#if !defined(symbol) #ifndef symbol 如果symbol没有被定义,这个条件就为真
#if 常量表达式
//...
#endif
//常量表达式由预处理器求值。
如:
#define __DEBUG__ 1
#if __DEBUG__
//..
#endif
2.多个分支的条件编译
#if 常量表达式
//...
#elif 常量表达式
//...
#else
//...
#endif
3.判断是否被定义
//只要symbol被定义,这个条件就为真,symbol为0也为真;
#if defined(symbol)
#ifdef symbol
//如果symbol没有被定义,这个条件就为真
#if !defined(symbol)
#ifndef symbol
4.嵌套指令
#if defined(OS_UNIX)
#ifdef OPTION1
unix_version_option1();
#endif
#ifdef OPTION2
unix_version_option2();
#endif
#elif defined(OS_MSDOS)
#ifdef OPTION2
msdos_version_option2();
#endif
#endif