C++入门教程(十一、宏)-创新互联

目录
  • 前面教程汇总
    • 第一讲
    • 第二讲
    • 第三讲
    • 第四讲
    • 第五讲
    • 第六讲
    • 第七讲
    • 第八讲
    • 第九讲
    • 第十讲
    • 什么是预处理?
    • 宏定义
      • 宏常量
      • 宏语句
    • 宏函数
    • `#undef` 指令
    • `ifndef` 指令
    • 宏定义相关作用符
      • 换行符 `\`
      • 字符串化符 `#`
      • 片段连接符 `##`

创新互联主要从事成都做网站、网站设计、网页设计、企业做网站、公司建网站等业务。立足成都服务淄博,十余年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575前面教程汇总 第一讲

C++入门教程(一、初步了解)

第二讲

C++入门教程(二、基本数据类型)

第三讲

C++入门教程(三、数组、注释与函数)

第四讲

C++入门教程(四、运算符与表达式)

第五讲

C++入门教程(五、数组与字符串)

第六讲

C++入门教程(六、指针)

第七讲

C++入门教程(七、结构体)

第八讲

C++入门教程(八、枚举类型)

第九讲

C++入门教程(九、语句与控制流)

第十讲

C++入门教程(十、联合体)

宏 什么是预处理?

编译一个C语言或C++程序的第一步骤就是预处理阶段,这一阶段就是宏发挥作用的阶段。C和C++的预处理器在源代码编译之前对其进行一些文本性质的操作,主要任务包括删除注释、插入被#include进来的文件内容、定义和替换由#define定义的符号以及确定代码部分内容是否根据条件编译(#if)来进行编译。“文本性质”的操作,就是指一段文本替换成另外一段文本,而不考虑其中任何的语义内容。宏仅仅是在C预处理阶段的一种文本替换工具,编译完之后对二进制代码不可见

宏定义 宏常量

很简单,格式是#define Object number,比如定义一个π的值:

#define PI 3.14

可以直接用:

#define PI 3.14
#includeusing namespace std;

int main()
{cout<< "圆周率约等于"<< PI<< endl;
	return 0;
}

输出结果:

3.14
宏语句

我们还可以用宏定义一条或多条语句。例如:

#include#define Print printf("hello world!")
using namespace std;

int main()
{Print;  //预处理时会被替换为 printf("hello world!");
	return 0;
}
宏函数

我们还可以用宏来定义函数。宏定义也可以带参数,例如:

#include#define Print(str) printf("%s",str)
using namespace std;

int main()
{Print("这是一个只有一条语句的宏函数!");
    //预处理时会被替换为 printf("%s","这是一个只有一条语句的宏函数!")
	return 0;
}
#undef指令

#undef是用来撤销宏定义的,用法如下:

#define PI 3.141592654
...
// code
#undef PI
//下面开始 PI 就失效了
ifndef指令

使用ifndef防止头文件被重复包含和编译。这是宏定义的一种,它可以根据是否已经定义了一个变量来进行分支选择,一般用于调试等等.实际上确切的说这应该是预处理功能中三种(宏定义,文件包含和条件编译)中的一种----条件编译。 C语言或C++在对程序进行编译时,会先根据预处理命令进行“预处理”。C语言和C++的编译系统包括预处理,编译和链接等部分。

#ifndef x //先测试x是否被宏定义过
#define x //如果没有宏定义下面就宏定义x并编译下面的语句
...
...
...
#endif //如果已经定义了则编译#endif后面的语句

条件指示符#ifndef检查预编译常量在前面是否已经被宏定义。如果在前面没有被宏定义,则条件指示符的值为真,于是从#ifndef#endif之间的所有语句都被包含进来进行编译处理。相反,如果#ifndef指示符的值为假,则它与#endif指示符之间的行将被忽略。条件指示符#ifndef的最主要目的是防止头文件的重复包含和编译。

千万不要忽略了头文件的中的#ifndef,这是一个很关键的东西。比如你有两个C(或C++)文件,这两个C(或C++)文件都include了同一个头文件。而编译时,这两个C(或C++)文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。

所以还是把头文件的内容都放在#ifndef#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的:

#ifndef<标识>#define<标识>...
#endif

<标识>在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如(这里以C语言举例子,因为这一讲的内容同时适用于C和C++):stdio.h

#ifndef _STDIO_H_
#define _STDIO_H_
......
#endif
#ifndef xxx //如果没有定义xxx
#define xxx //定义xxx
#endif //结束如果

这个用法主要是在头文件中,主要是为了防止类重复的include,所以在类的头文件之前加上前面两个,用类名替代xxx,在最后加上最后一句。

宏定义相关作用符 换行符\

我们定义宏语句或者宏函数时不可能总是一条语句呀,那要是有很多条语句时怎么办?都写在一行吗?这样显然代码就不美观,可读性不好。所以有多条语句时,我们就在每行末尾(除了最后一行)加上\,代表换行的意思。
例如:

#include#define Print   printf("这是第1条语句\n");\
 		    	printf("这是第2条语句\n");\
 		    	printf("这是第3条语句\n")
 		    	
#define Show(str1,str2,str3)\
{\
	printf("%s\n",str1);\
	printf("%s\n",str2);\
	printf("%s\n",str3);\	
}
using namespace std;

int main()
{Print;  //无参数宏函数
	Show("first","second","third"); //带参数宏函数
	return 0;
}
字符串化符#

#是“字符串化”的意思,将出现在宏定义中的#是把跟在后面的参数转换成一个字符串。
例如:

#include#define Print(str)\
{\
	printf(#str"的值是%d",str);\	
}
using namespace std;

int main()
{int x=3,y=4;
	Print(x+y); //此处等价于printf("x+y""的值是%d",x+y);
	            //#str等价于"x+y",所以#str不需要再用双引号引起来 
	return 0;
}
片段连接符##

##是一种分隔连接方式,它的作用是先分隔,然后进行强制连接。在普通的宏定义中,预处理器一般把空格解释成分段标志,对于每一段和前面比较,相同的就被替换。但是这样做的结果是,被替换段之间存在一些空格。如果我们不希望出现这些空格,就可以通过添加一些##来替代空格。
例:

#include#define Add(n,value)\
{\
	num##n+=value;\
}
using namespace std;

int main()
{int num1=1;
	int num2=10;
	Add(2,10); //等价于num2+=10; 这里把num和2连接成了num2 
	printf(" num1=%d\n num2=%d",num1,num2); 
	return 0;
}

关于宏的内容还有很多,需要大家慢慢摸索,这里我就不再过多的介绍了(因为我不是特别喜欢用宏,喜欢用普通的const常量和函数等,因为它会无视很多限制,所以在大型场合下人们都会说宏是一种危险的东西)。注意,这只是入门教程,目的是让人们熟悉C++(因为我写的内容里面有很多带有C语言味,比如我总是用printf,而且我也C语言写惯了,所以大家也应该会熟悉C语言),而不是精通C和C++。我也不是C和C++方面的专家(特别厉害的),所以想要深入学习,还是得请大咖(非常无奈)。但是我为了教大家C++投入了很多时间,所以如果能得到你们的赞,那就太好了。

本文完。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


文章标题:C++入门教程(十一、宏)-创新互联
URL链接:http://myzitong.com/article/pcdjh.html