#define和#、##、@#解析:

目录

前言:

1.什么是预处理:

2.#define是什么:

一.关于#define:

1).#define 的标识符定义:

2).#define 的函数定义:

3)#define 的续行操作:

4)#define 的常见作用:

a.方便维护:

b.方便程序员检测:

c.简化写法:

d.进行条件编译:

二.关于字符串常量化运算符 # :

1).常见用法:

2).对空格处理:

三.符号连接操作符符 ##:

四.单字符化操作符 #@ :

注意事项:


前言:

1.什么是预处理:

C语言源文件要经过预处理、编译、链接才能生成可执行程序。

预处理就是再编译前,对源文件进行简单的加工处理。

预处理主要是以 # 开头的命令,例如 #include<stdio.h> #define 等。

预处理命令要放在所有函数之外,而且一般都放在源文件的前面。

2.#define是什么:

#define 属于预处理器指令,可以将一些常量或代码模块定义为宏,在预处理是进行文本替换,这个行为被称为宏替换或宏展开。

一.关于#define:

1).#define 的标识符定义:

定义标识符是 #define 最常见的用法,也可以说是没有参数的宏定义。

流程为:

#define -----> 标识符(也叫宏名、宏) ------>替换列表。

示例:

#include<stdio.h>
#define num 20
#define print printf
int main()
{
	print("%d", num);
	return 0;
}

运行结果如下图:

这里是一个简单的宏定义,我们使用预处理指令 #define 定义了一个名为 print 和 num,“printf” 和“num"  在预处理阶段会被替换成函数 printf 和 20。

2).#define 的函数定义:

简单来说,就是 #define 的宏定义可以像函数一样接受参数。

示例:

#include<stdio.h>
#define add(x, y) ((x)+(y))
#define max(x, y)  ((x) > (y) ?x:y)
int main()
{
	printf("%d\n", add(2, 3));
	printf("%d\n", max(2, 3));
	return 0;
}

运行结果如下图所示:

这里我们定义了两个名为 add ,max 的宏,进行文本替换后分别求出参数之和和参数中最大值。

3)#define 的续行操作:

顾名思义就是将 #define 的替换列表放在二行及更多行上。

示例:

#include<stdio.h>
#define for(x) for(int i = 0; i < x; i++)\
{\
	printf("%2d",i);\
}
int main()
{
	for (5);
	return 0;
}

运行结果如下图:

 

由上,我们可以知道,#define 的多行定义关键是要在每一个换行的时候加上一个"/"。

4)#define 的常见作用:

a.方便维护:

示例:

#define size 100;
int a[size];

这里创建了一个数组,当以后数组觉得数组太大或是太小,我们可以通过改变宏定义的替换列表来一键改变数组 a 的大小。

b.方便程序员检测:

当看别人的代码时,或者回头观看以前的代码,通常会忘记一个代码块代表的含义,当使用如 add  等宏定义的函数时,可以帮助我们快速理解。

c.简化写法:

示例:

#define usi  unsigned short int
usi a;

当我们需要经常使用 unsigned short int 时,由于该类型较长,经常会 觉得麻烦,这时候就可以通过将其定义为 usi ,并可以通过 usi 创建变量。

d.进行条件编译:

示例:

#include<stdio.h>
#define add 0
int main()
{
#ifdef add
	printf("1");
#endif
	return 0;
}

运行结果如下:

 

如上图,当 add 被定义时,预处理指令 #ifdef 和 #endif 中的语句执行,当讲 add 的宏定义注释掉时,预处理指令中的语句不执行。 

二.关于字符串常量化运算符 # :

1).常见用法:

示例:

#include<stdio.h>
#define print(a,b) printf(#a" and %d",b)
int main()
{
	print(abc,3);
	return 0;
}

运行结果如下图所示:

 

 由此,我们可以知道,在宏定义中,当需要把一个宏的参数转换为字符串常量时,则使用字符串常量化运算符(#)。在宏中使用的该运算符有一个特定的参数或参数列表。

2).对空格处理:

示例:

#include<stdio.h>
#define print(a,b) printf(#a" and %d",b)
int main()
{
	print(   a   bc   ,3);
	return 0;
}

运行结果如下图: 

由此,我们可以知道,编译器会将子字符或者字子符串使用空格连接,并丢弃字符或字符串两边的空格。

三.符号连接操作符符 ##:

示例:

#include<stdio.h>
#define num1 100
#define num(a) num##a
int main()
{
	printf("%d", num(1));
	return 0;
}

运行结果如下图:

 

这里我们通过符号链接操作符 ## 将 num 和 1 连接成 num1 。

注:1).宏展开时, ## 两边的空格会自动去除。

        2).连接后的实际参数名,必须为实际存在的参数名或是编译器已知的宏定义。

        3).如果##后的参数本身也是一个宏的话,##会阻止这个宏的展开。

四.单字符化操作符 #@ :

用法与##类似。

示例:

#include<stdio.h>
#define fun(x) #@x
int main()
{
	printf("%c", fun(a));
	return 0;
}

运行结果如下所示:

 

这里通过 #@ 操作符,将 a 转换成字符。

注:单字符化操作符#@ 最多有四个参数,并只返回最后一个字符,当参数超过四个时,系统将报错。

注意事项:

1.define是宏定义,程序在预处理阶段将用define定义的内容进行了 替换 。因此在程序运行时,常量表中并没有用define定义的常量,系统不为它分配内存。

2.define没有类型检查的功能,因为它只进行文本替换。它只是简单地将宏调用替换为宏定义中指定的文本,没有对文本进行语法分析和类型检查。这种情况下,类型错误很容易发生,特别是对于复杂的宏定义。

3.define定义表达式时要注意“边缘效应”。

示例:

#include<stdio.h>
#define fun(a,b) a+b
int main()
{
	printf("%d", fun(1, 2) * fun(3, 4));
	return 0;
}

运行结果如下所示:

 

对于这个代码,我们想得到的值为21, 但是实际的值为11 。这是为什么?我们将宏展开看看:

#include<stdio.h>
int main()
{
	printf("%d", 1+2*3+4);
	return 0;
}

这里,本应该先和 1 相加的 2 却先与 3 相乘,所以结果错误。 

我们可以通过多加括号,来改变表达式运算顺序来预防“边缘效应”。

4.define 宏定义后,直到遇到 #undef 之前可以一直使用;在 #undef 后,先前的宏需要再次定义才能够使用。

5.带副作用的宏参数:

示例:

#include<stdio.h>
#define max(x,y) ((x)>(y)?(x):(y))
int main()
{
	int a = 1, b = 2;
	int c = max(++a, ++b);
	printf("%d", c);
	return 0;
}

这里宏展开后得到表达式 c = ((++a)>(++b)?(++a):(++b)),这个式子的值与编译器有关,就大大降低了代码的可移植性。

  • 33
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值