一、defined

我们在介绍#if时就介绍过defined的使用,它常与#if!配合使用

#if defined MACRO1 && !defined MACRO2
...

#endif

二、#line

作用

可以根据你自己的需求,修改__LINE____FILE__的值,也就是修改行号和文件名
修改的值永久生效

举例理解:
test.c

#include <stdio.h>

int main(void)
{
#line 1 "t.c"
    printf("%d %s\n", __LINE__, __FILE__);

    return 0;
}

查看预编译结果:

......
# 3 "test.c"
int main(void)
{
# 1 "t.c"  // 含义:从下行开始,行号从1开始,文件名是t.c
    printf("%d %s\n", 1, "t.c");

    return 0;
}

使用#line修改行号和文件名有什么意义?
实际上对于我们自己写C/c++程序而言,几乎用不到#line这个东西,只有我们在看某些源码时才会见到它

至于使用#line修改行号和文件名,到底有什么意义,这个问题我们这里不介绍,
因为一两句话说不清楚,我们只要知道#line的作用是修改行号和文件名就行


三、 # 

很多学习C语言的同学很容易忽略这两个东西,但是在源码中,这两个玩意经常出现。
大家在理解了###的用法后,也希望大家在自己的C程序中使用,以提高自己代码质量。

作用:将宏参数变为字符串

这里讲的##define#include中的#的作用是不同的,不要搞混了

(2)例子
1)例子1

#include <stdio.h>

#define STR(s) #s

int main(void)
{
    printf("%s\n", STR(hello world));

    return 0;
}

STR(hello world)的替换过程:

STR(hello world) ————————>#hello wolrd ——————> "hello world"

查看预编译后的结果:

......
# 5 "helloworld.c"
int main(void)
{
 printf("%s\n", "hello world");

 return 0;
}

疑问:# 5 "helloworld.c"是什么意思?

表示.i中该部分的内容,来至于那个文件

2)例子2

#include <stdio.h>

#define STR1(s) #s" wolrd"
#define STR2(s) "hello "#s

int main(void)
{
    printf("%s\n", STR1(hello));
    printf("%s\n", STR2(world));

    return 0;
}

查看预编译后的结果:

int main(void)
{
    printf("%s\n", "hello"" wolrd"); 
    printf("%s\n", "hello ""world");

    return 0;
}

疑问: "hello"" wolrd"这种写法可以吗?

答:可以,与"hello world"是等价的

STR1(hello)   #hello" wolrd"  "hello"" wolrd"

四、 ## 

作用:将两个标识符连接在一起,合成一个标识符

(2)例子

#include <stdio.h>

#define ADDR1 0x12343654
#define ADDR2 0x54543243

#define MACRO(a, b) a##b

int main(void)
{
    int *p = MACRO(ADDR, 1);

    return 0;
}

MACRO(ADDR, 1)处理的过程:

MACRO(ADDR, 1) ——————> ADDR##1 ———————> ADDR1 ————————>0x12343654

查看预编译后的结果:

int main(void)
{
    int *p = 0x12343654;
    return 0;
}