预处理在c语言中的作用,C语言(预处理)

预处理指令

预处理指令以#开头,编译前执行

include指令

作用

文件包含命令,引入对应头文件

处理过程

将头文件的内容(.h)插入到该命令所在的位置,从而把头文件和当前源文件连接成一个源文件,等同复制粘贴效果。

include用法及区别

#include

#include "myHeader.h"

使用尖括号<

>,编译器会到系统路径下查找头文件;而使用双引号"

",编译器首先在当前目录下查找头文件,如果没有找到,再到系统路径下查找。

最佳习惯:使用尖括号来引入标准头文件,使用双引号来引入自定义头文件,禁用绝对路径作为搜索路径(如开发移植到生产路径发生变化出问题)

<>搜索顺序

在编译器设置的include路径内搜索;

如果找不到,则在系统的include环境变量内搜索;

linux下标准路径

/usr/include,/usr/local/include

可以在/usr/include/sys目录下发现io.h

指定路径下检索头文件

#/home/Desktop目录下有个头文件local1.h,编译包含local1.h的test.c文件时

gcc test.c -o test -I /root/Desktop

pragma指令

作用

设定编译器的状态或者是指示编译器完成一些特定的动作。编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。

命令格式

#pragma para

常用参数

#pragma message("消息文本")

在编译信息输出窗口中输出相应的信息

eg:#ifdef _X86

#pragma message("_X86 macro

activated!")

#endif

编译的时候就进行检查宏的设置

#开发驱动程序常用

#pragma code_seg( ["section-name" [,

"section-class"] ] )

#pragma once

在头文件的最开始加入这条指令就能够保证头文件被编译一次

#pragma warning( disable: 4507 34;

once: 4385; error: 164 )

// 不显示4507和34号警告信息

// 4385号警告信息仅报告一次

// 把164号警告信息作为一个错误。

#pragma warning( push

)保存所有警告信息的现有的警告状态。

#pragma warning( push, n

)保存所有警告信息的现有的警告状态,并且把全局警告等级设定为n。

#pragma warning( pop

)向栈中弹出最后一个警告信息,在入栈和出栈之间所作的一切改动取消

#将一个注释记录放入一个对象文件或可执行文件

#pragma comment(lib,

"wsock32.lib")

#pragma pack(n)

内存对齐

许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,而这个k则被称为该数据类型的对齐模数(alignment

modulus)。任何基本数据类型T的对齐模数就是T的大小,即sizeof(T)。

Win32平台下的微软C编译器(cl.exe for 80x86)

n字节边界对齐的意思是说,一个成员的地址必须安排在成员的尺寸的整数倍地址上或者是n的整数倍地址上,取它们中的最小值。

c/c++中的对齐选项:/Zp[1|2|4|8|16]

min ( sizeof ( member ), n)

栈内存对齐

注:在vc6中栈的对齐方式不受结构成员对齐选项的影响。它总保持对齐,而且对齐在4字节边界。

宏定义

作用

将宏名替换为字符串(宏替换)

格式

#define 宏名 字符串 #宏名大写

用法

eg1.常量替换,增加程序可读性

#define PI 3.14159

eg2.宏定义表示数据类型,方便书写

#define UINT unsigned int

UINT a, b; => unsigned int

a,b;

与typedef自定义数据类型的区别

1.宏定义只是简单的字符串替换,由预处理器来处理;

2. typedef

是在编译阶段由编译器处理的,给原有的数据类型起一个新的名字,将它作为一种新的数据类型。

#define PIN1 int *

typedef int *PIN2;

//也可以写作typedef int (*PIN2);

PIN1 a, b; => int * a,

b;

PIN2 a,b; => int *a,*b;

eg3.定义表达式 (替换变量字符串括号不能少)

#define SUM(a,b) ((a)*(b))

调试宏(编译器内置)

__FILE__ 当前程序文件名

__LINE__ 当前行号

__FUNCTION__ 函数名称

__DATE__ 当前日期

__STDC__ 编译器遵循ANSI C标准,非零

__TIME__ 当前时间

预处理运算符

1.字符串化运算符 —— #

用于创建字符串,#运算符后面应该跟一个形参。

#define Dump_Str(s) printf("%s =

%s\n",#s,s);

const char * pchName = "Gui xue";

Dump_Str(pchName);

//输出 pchName = Gui xue

2.连接运算符 —— ##

用于将两个Token连接成一个Token;

#define __CONCAT(x,y) x ## y

int n1 =15;

int n2 =200;

__CONCAT(n,1); // n1

__CONCAT(n,2); // n2

3.字符化运算符—— #@

用于创建一个字符,类似 ## ,注: 非

ANSI-C中的特性,GCC不支持,VC可以;

#define Dump_Char(c) #@c

printf("%c/n",Dump_Char(g)); //g

printf("%c/n",Dump_Char(guix)); //x 可以输入

4个长度的字符,但只输出最后一位

printf("%c/n",Dump_Char( guix )); //x

默认去除前后空格,保留中间空格

printf("%c/n",Dump_Char(guixu));

//error C2015: too many characters in

constant

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值