c中对宏的理解(面试题)

1、gcc的编译过程:预处理、编译、汇编、链接

在这里插入图片描述

预处理:宏替换、删除注释、头文件包含、条件编译 -E (不会发生报错)生成预编译文件
将 01_code.c文件使用 gcc -E 01_code.c -o 01.i生成预编译文件01.i
在这里插入图片描述
可以10行的源文件看见生成800多行的预编译文件
在这里插入图片描述

编译:将预编译之后的文件编译成汇编文件
在这里插入图片描述
在这里插入图片描述

汇编:将汇编文件生成二进制文件
在这里插入图片描述

在这里插入图片描述

链接:将工程中的各个二进制文件+库函数+启动文件 生成可执行文件

edu@edu:~/work/c/day_03$ gcc 01.o -o 01

在这里插入图片描述

或者可以直接由预编译文件一步到位

在这里插入图片描述

2、宏的了解

使用关键字define叫做宏

#define MA 3                          //宏的定义形式(宏定义)

在预处理的时候使用 3 代替所有MA出现的位置(宏展开)
注意:不要再宏后面加 分号

#define MA 3;                          //错误的宏定义形式
if (MA>2){   //这个表达式中 就会出现 3; > 2这样的情况,所以加分号这种宏定义形式是错误的
   printf("大于\n");
}

3、不带参数的宏

宏的定义范围:是从定义处开始当前文件结束 都有效
#under可以结束宏的作用域(但是这个是不常用的)
宏没有归属,只有在当前文件中有效


#include <stdio.h>
void test06()
{
#define N 100 // 宏没有归属感,只要不影响使用,可以定义在当前文件中的任何位置中,所以这种定义方式也是正确的
    printf("N = %d\n", N);
}
int main(int argc, char const *argv[])
{
    test06();
    return 0;
}

在这里插入图片描述

4、带参数的宏

#include <stdio.h>
#define MY(a, b) a *b
void test00()
{
    printf("MY(a,b) = %d\n", MY(2, 3)); // 使用 10*20代替 MY(2, 3)
}
int main()
{
    test00();
}

在这里插入图片描述
使用 gcc -E 01_code.c -o 01.i进行预编译在这里插入图片描述
在这里插入图片描述

注意事项:

(1)、宏定义的时候不能有数据类型
在这里插入图片描述
(2)、宏定义不能保证参数的完整性

#include <stdio.h>
#define MY(a, b) a *b
#define MY_1(a, b) a *b
#define MY_2(a, b) ((a) * (b))
#define MY_3(a, b) (a) * (b)
void test00()
{
    printf("MY(a,b) = %d\n", MY(2, 3));             // 使用 a*b代替 MY(2, 3)
    printf("MY_1(a,b) = %d\n", MY_1(2 + 2, 3 + 3)); // 2 + 2 * 3 + 3
    printf("MY_2(a,b) = %d\n", MY_2(2 + 2, 3 + 3)); //((2+2) * (3 + 3))
    printf("MY_3(a,b) = %d\n", MY_3(2 + 2, 3 + 3)); //(2+2) * (3 + 3)
}
int main()
{
    test00();
}

在这里插入图片描述
(3)、宏不能作为 类、结构体的成员

5、带参宏(宏函数)和带参函数的区别

(1)、带参宏调用多少次就会展开多少次,执行代码的时候没有函数的调用过程,不需要压栈和弹栈,所以带参宏是浪费了栈的空间,因为在预编译的时候被多次展开,所以节省时间(典型的使用空间换取时间)
(2)、带参数的函数,只有一段,存储在代码段,所以在编译阶段会进行多次压入栈中、退出栈中,所以节省了空间,但是压栈和退栈浪费了时间(典型的使用时间换取空间)
(3)、带参数的函数中的参数有数据类型定义,但是带参宏中没有数据类型的定义

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Q渡劫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值