20170214C语言提升07_预编译指令

预编译指令:

条件编译指令:属于编译环境和编译器之间的交流指令,预编译指令控制的是代码。
#include <stdio.h>

#define DEMO 5

#ifndef DEMO//如果没有定义DEMO做的事情
int num = 0;
#endif // !DEMO
#ifdef DEMO//如果定义了DEMO要做的事情
int num = 100;
#endif // !DEMO
//

int main()
{
	printf("%d", num);

#if (DEMO==0)//这里条件必须是使用预编译时候就有的条件,不可以使用num等变量。num要与处理完之后才有的。
	printf("DEMO == 0\r\n");
#elif(DEMO == 1)
	printf("DEMO == 1");
#else
	printf("DEMO!=0 && DEMO!=1");
#endif

	return 0;
}

如果两个.h文件互相包含,main.c里面包含任何一个.h,编译的时候就会导致递归,包含了无穷个.h。这种情况就是用宏来做
#ifndef 
#define
#endif
用这个来防止一个库文件被多次包含。
宏定义还可以在属性里面的预处理器和命令行里面进行添加,命令行里面可以给宏定义赋值。

错误提示预编译指令:

用在编译的时候提示错误。
#include <stdio.h>

#define ERROR

int main()
{
#ifdef ERROR
#error You Are Error
#endif
	printf("222");
	return 0;
}

上面这段代码再便宜的时候就会提示出错误,并打印#error后面的文字。多用于多人协作的时候使用。
#warning已被遗弃,用法差不多的。

设置文件名及行号:

将对应地点的行号进行设置,文件名也对应设置
#include <stdio.h>
#line 100 "main.c"
int main()
{
	printf("%s中的第%d行", __FILE__, __LINE__);
	return 0;
}

#line后面的第一个数字代表当前行的下一行行号被设置成这个数,后面的字符串代表文件名被改成这个名字。

版本控制利器#Pragma message:

1:特殊的预编译指令:实际叫做预编译指示字。
2:#pragma是一个指示字,不同的C语言编译器对他的理解是不同的,这个是没有标准的。
3:它不具有移植性,但是如果一个编译器发现了一个他没有定义的预编译指示字的时候,他会忽略。不影响移植性。
4:他并非作用于代码,它主要的作用是指示编译器来完成特殊的指令。
#include <stdio.h>

#define VER 1
#if(VER == 1)
#pragma message("版本1.0")//message指示字是VS特有的。这些并不作用于代码,只是在编译的时候输出信息
#endif
int main()
{
	return 0;
}

BAT名企敲门砖-高端面试之内存对齐:

1:#pragma pack(2)//内存对齐控制指示字,里面的数字必须为1 2 4 8 16 32。
2:内存对齐是为了方便cpu对数据的读取,cpu是按照块来读取的。
    注意:有的cpu可能只会从偶数位的地址开始读取,如果为奇数,可能报硬件错误。
3:默认的对其方式是4。程序编译器对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。
4:对其的时候,会首选较小的数据类型扩大。例如默认的对齐方式是4byte,如果一个结构体为struct s1 {short s;int n;};,那么他占用空间为8byte,short为前2byte,空2byte,后四个为int。这种更方便cpu读取。具体准确规则比较复杂,通过下面的例子来看
#include <stdio.h>

//内存的对齐方式控制的指示字
#pragma pack(4)//里面跟的数字必须为1 2 4 8 16  数据对齐方式
struct s1 
{
	short s;	//2byte
	int n;		//4byte
	char c;
};
struct s2 
{
	char c;		//1byte
	struct s1 s;	//它使用的对齐方式为里面成员使用的对齐参数的最大值 4
	double d;	//8byte
};
struct s3 //偏移是内存地址的偏移(必须可整除对齐参数),pack是设置的,size是数据类型大小,对齐参数是pack和size取小值,结果为占用内存位置空间
{	//			偏移		pack	size	对齐参数	结果
	char c;//		0		4	1	1		0
	int n;//		4		4	4	4		4-7
	short s;//		8		4	2	2		8-9
	char c1;//		10		4	1	1		10
	long l;//		12		4	4	4		12-15
	double d;//		16		4	8	4		16-23
};//总长度必须可以整除对齐参数
#pragma pack()

int main()
{
	printf("%d\r\n", sizeof(struct s1));
	printf("%d\r\n", sizeof(struct s2));
	printf("%d\r\n", sizeof(struct s3));
	struct s3 ss3;
	ss3.c = 'a'; ss3.c1 = 'b'; ss3.d = 100; ss3.l = 50; ss3.n = 25; ss3.s = 12;
	return 0;
}

奇淫意巧-生态生成变量名:

1:宏定义的时候使用的#号,可以将其他的转化为字符串:
#include <stdio.h>

#define ERROR(n) #n
int main()
{
	int error_code = 10;
	printf("%s", ERROR(100));//将打印100
	return 0;
}

2:##的使用:
#include <stdio.h>

#define STR(n) #n//#号的使用,转化成字符串
#define NO(n) No##n//##的使用,代表连接符
/*
#define STRUCT(type) typedef struct tag_##type; struct tag_##type;	//上课讲了,但运行出错
STRUCT(S1)
{
	int i;
};*/
int main()
{
	int error_code = 10;
	printf("%s", STR(100));//将打印100

	int NO(1);
	int NO(2);
	int NO(3);
	for (int i = 0; i < 20; ++i)
	{
		printf("%s\r\n", STR(NO(i)));//这里会打印20个NOi。他只会认里面的直接字。
	}
	/*S1 s;
	s.i = 100;*/	
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值