栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

浅谈C语言预定义中的预定义符号,#define,以及符号#,##的相关运用

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

浅谈C语言预定义中的预定义符号,#define,以及符号#,##的相关运用

浅谈C语言预定义中的预定义符号,#define,以及符号#,##的相关运用
求个赞求个赞求个赞求个赞 谢谢

先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记关注我哦!️️️
本章节对于初学者来说,是比较简单的,而且我个人认为也非常的有趣,我相信大部分的小伙伴都可以理解

文章目录
    • 预定义符号的介绍
    • #define定义符号
    • #define定义宏
    • #符号的使用
    • ##符号的使用
    • 尾声

预定义符号的介绍

一下这些符号是不需要#define来进行定义的,是本身就定义好我们可以直接使用的符号。

__FILE__;进行编译的源文件
__LINE__;文件当前的行号
__DATE__;文件被编译的日期
__TIME__;文件被编译的时间
__STDC__;如果编译器遵循ANSI C,则其值为1,否则未定义
__FUNCTION__;当前运行的函数

我们可以输入程序打印出来看看

int main()
{
	printf("%sn", __FILE__);
	printf("%dn", __LINE__);
	printf("%sn", __DATE__);
	printf("%sn", __TIME__);
	printf("%sn", __FUNCTION__);
	return 0;
}

我们可以依次看到,文件的位置,当前的行数,编译的日期,时间,当前的函数
有了这些,我们就可以在写代码的同时写日志了

int main()
{
	int i = 0;
	FILE* pf = fopen("log.txt", "a+");//追加的形式输入
	if (pf == NULL)//判断文件是否打开成功
	{
		perror("fopenn");
		return 1;
	}
	for (i = 0; i < 10; i++)
	{
		fprintf(pf, "%s %d %s %s %dn", __FILE__, __LINE__, __DATE__, __TIME__, i);
		//将我们的写代码时的信息存入log.txt这个文件里面
	}
	return 0;
}


这样,我们就可以把我们想要记录的信息存放到文件中了

#define定义符号

只要学过程序环境以及编译过程的伙伴,对#define所执行的方式都不陌生
#define所定义的符号,在预处理过程中就会被直接替换到函数里面。

#define M 1000;
#define reg register
#define do_forever for(;;)
int main()
{
	reg int num = 0;
	do_forever;//替换,变成了死循环了
	int m = M;///在预处理过程,M已经被替换成1000了
	printf("%dn",m);
	return 0;
}

#define因为是直接替换,所以利用#define来定义常量在实现一些游戏程序的时候是很方便的,比如,我们写一个三子棋,(或者扫雷),我们需要定义二维数组,此时,我们可以直接定义char board[3][3]={0};,如果这样创建数组,以后每一次我们使用这个数组定义新函数的时候,我们都要输入这个3和3,如果有一天我想要把三子棋改成五子棋,那么我们修改的工作量就会比较大。
因此,我们可以使用#define语句来定义常量

#define ROW 3
#define COL 3
int main()
{
    char board[ROW][COL]={0};
    //.....实现过程
    return 0;
}

这样我们以后修改的时候,只需要修改#define时候的数字就可以了

#define定义宏

我们先来看一个简单的用法

#define SQUARE(X) X*X
int main()
{
    int a=3;
    int ret=SQUARE(a);
    printf("%d",a);
    return 0;
}

这样我们得到的结果是9,这种用法其实也是直接替换,将X*X替换成SQUARE(X),所以答案是9
注意:#define定义的宏是直接的替换,不会做任何的运算,下面我们来看两个个例子

#define SQUARE(X) X*X
#define DOUBLE(X) (X)+(X)
int main()
{
	printf("%dn", SQUARE(3+1));
	//注意:宏是直接完全替换的,而不会去搞计算
	//上面这一句等同于下面这一句--完全的直接的替换
	printf("%dn", 3 + 1 * 3 + 1);
	//所以结果是7
	//替换是在预处理阶段就完成的,而计算结果是在运行的时候
	//想要得到16,我们可以这样写
	//#define SQUARE(X) ((X)*(X))
	//这样写才是最严谨的
	//写宏的的时候,括号很重要,但是有时候括号也会带来问题
	printf("%dn", 10 * DOUBLE(4));//这里是得不到八十的
	printf("%dn", 10 * (4) + (4));
	return 0;
}

很多小伙伴都误认为第一题是16,第二题是80,通过我写的注释我们可以得知,这个替换是直接进行的,不会进行运算
因此第一题变成了3+1*3+1,结果当然不是16,第二题同理。
一下也是一种用法

#define MAX(X,Y) ((X)>(Y)?(X):(Y))
int main()
{
	int max = MAX(101, 100);
	//跟函数传参完全不同,这里是替换进去
	return 0;
}

//注意:宏参数和#define定义中可以出现其他#define定义的变量。但是对于宏,不能出现递归
//      当预处理器搜索#define定义的符号的时候,字符串常量的内容不被搜索

那么如何把参数插入到字符串中呢?

#符号的使用

我们先来看以下这个场景

int main()
{
    int a=10;
    int b=20;
    int c=30;
    //现在想要打印三句话
    printf("the value of a is %dn",a);
    printf("the value of b is %dn",b);
    printf("the value of c is %dn",c);
    //这样写的话我们的the value of...is这些语句就重复写了三次
    return 0;
}

这样写的话我们的the value of…is这些语句就重复写了三次,那么有没有什么更简单的方法?这时候,很多小伙伴都会想,我们可以使用函数,传参不就好了?但事实上操作起来,函数实现是非常麻烦的,因为the value of后面这个字符是会变的,不相信的小伙伴可以使用函数做一些尝试。
因此这个时候我们就可以利用#这个操作符来帮助我们完成

#define PRINT(X) printf("the value of "#X" is %dn",X);
//                                     ^此#非前面的#
//                                     ^此处如果没有#,就会被替换,代码就会出错了
//但是如果加上#,就不是替换了,#X就会变成X的内容所对应的字符串
int main()
{
	int a = 10;
	PRINT(a);//这一句跟下面这一句是完全等价的
	printf("the value of ""a"" is %dn", a);
	int b = 20;
	PRINT(b);
	printf("the value of ""b"" is %dn", b);
	int c = 30;
	PRINT(c);
	printf("the value of ""c"" is %dn", c);
	return 0;
}

通过这种方式,我们就可以只是用三个PRINT()就可以完成我们的任务了
注意:定义宏的时候,两个字符串中间的X如果不加上#,就会被直接替换,这样的话代码是会出问题的
但是,如果我们加上#,就不是直接替换了,#X就会变成X的内容所对应的字符串
这样,我们就能很好的实现我们的功能
如果有不同类型的数据,我们还可以稍微优化一下我们的代码

//我们还可以把上面的代码稍微优化一下
//#X这个#只能在宏上面用
#define PRINT(X,FORMAT) printf("the value of "#X" is "FORMAT"n",X)
int main()
{
	int a = 10;
	PRINT(a, "%d");
	int b = 20;
	PRINT(b, "%d");
	int c = 30;
	PRINT(c, "%d");
	float f = 5.5f;
	PRINT(f, "%f");
	return 0;
}

注意,#X只能在宏上使用

##符号的使用

个人认为,这个符号完成的算是个比较有趣的功能
它可以把两个符号连成一个符号

#define CAT(X,Y) X##Y
//可以把两个符号连成一个符号
int main()
{
	int grade9 = 100;
	printf("%dn", CAT(grad, e9));
	//这里的CAT是直接把grad和e9连起来,所以打印的当然是100
	return 0;
}
尾声

看到这里,相信你对预定义中的与定义符号,#define,以及符号#,##的相关运用已经有了一定认识,如果你感觉这期博客对你有帮助的话,请不要吝啬你们的点赞收藏和关注哦

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/395861.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号