预处理与结构体

一、预处理功能包括哪些

宏定义、文件包含、条件编译

二、宏定义的说明

1、 宏定义不是说明或语句,不需要在结尾加上分号
2、宏定义必须写在函数之外,其作用域是宏定义命令起到源程序结束,如需要终止可使用#undef命令
3、预处理程序不对宏定义做任何检查,如有错误,只能在编译被宏定义展开后的源程序时发现

三、带参数宏定义与自定义函数的区别

1、宏会在编译器在对源代码进行编译的时候进行简单替换,不会进行任何逻辑检测,即简单代码复制而已。
2、宏进行定义时不会考虑参数的类型。
3、参数宏的使用会使具有同一作用的代码块在目标文件中存在多个副本,即会增长目标文件的大小。
4、参数宏的运行速度会比函数快,因为不需要参数压栈/出栈操作。
5、参数宏在定义时要多加小心,多加括号。
6、函数只在目标文件中存在一处,比较节省程序空间。
7、函数的调用会牵扯到参数的传递,压栈/出栈操作,速度相对较慢。
8、函数的参数存在传值和传地址(指针)的问题,参数宏不存在

四、什么是条件编译

预处理程序提供了条件编译的功能。条件编译允许只编译源文件中满足条件的程序 段,使生成的目标程序较短,从而减少了内存的开销,并提高程序的效率,可以按不同的 条件去编译不同的程序部分,因而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。
第一种形式:

#ifdef 标识符
程序段1
#else
程序段2
#endif

第二种形式:

#ifndef 标识符
程序段1
#else
程序段2
#endif

第三种形式:

#if 常量表达式
程序段1
#else
程序段2
#endif

五、宏定义的几个使用技巧

1.防止一个头文件被重复包含

   #ifndef BODYDEF_H
   #define BODYDEF_H
   //头文件内容
   #endif

2、求最大值和最小值

   #define  MAX(x,y) (((x)>(y))?(x):(y))
   #define  MIN(x,y) (((x)<(y))?(x):(y))          

3、防止溢出的一个方法

   #define  INC_SAT(val)  (val = ((val)+1 > (val)) ? (val)+1 : (val))  

六、结构与数组的比较

1、都由多个元素组成
2、各个元素在内存中的存储空间是连续的
3、数组中各个元素的数据类型相同,而结构体中的各个元素的数据类型可以不相同

七、结构体的定义和使用

定义一个结构的一般形式为:

struct 结构名
{
成员表列
}

成员表由若干个成员组成,每个成员都是该结构的一个组成部分。

对每个成员也必须作类型说明。

例如:

struct stu
{
int num;
char name[20];
int age;
}

结构体定义并不是定义一个变量,而是定义了一种数据类型,这种类型是你定义的,它可以和语言本身所自有的简单数据类型一样使用(如 int )。
结构体本身并不会被作为数据而开辟内存,真正作为数据而在内存中存储的是这种结构体所定义的变量。

一个结构体变量占多大内存空间呢?这是由这种结构体类型的定义决定的,可以想象为了同时存储结构体的每一个成员,那么结构体变量的存储大小,就应该是所有分量的存储空间的总合。
说明结构变量有以下三种方法。以上面定义的stu为例来加以说明。

八、内存的对齐正式原则

(1).数据成员的对齐规则:结构体(struct)(或者联合体(union))的数据成员,第一个数据成员放在偏移量为0的地方,以后每个数据成员按照#pragma pack(n)和数据成员中比较小的那个数对齐,也就是说,起始地址需要时这个数的倍数,具体下面会举例说明;
(2).结构体(struct)(或者联合体(union))整体对齐规则:整体的大小应该按照#pragma pack(n)和结构中最长的数据结构中,最大的那个进行,也就是,需要时间这个数的倍数;
(3).如果#pragma pack(n)比结构中任何一个数据成员类型都大,则对齐系数不起任何作用。下面举例说明,环境:VS2013,32位操作系统

九、#define与typedef的区别

1、执行时间不同
关键字typedef在编译阶段有效,由于是在编译阶段,因此typedef有类型检查的功能。
#define则是宏定义,发生在预处理阶段,也就是编译之前,它只进行简单而机械的字符串替换,而不进行任何检查。

2、功能有差异
typedef用来定义类型的别名,定义与平台无关的数据类型,与struct的结合使用等。
#define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。

3、作用域不同
#define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用。
而typedef有自己的作用域。

十、位段的使用

(1)一个位段必须存储在同一存储单元(即字)之中,不能跨两个单元。如果其单元空间不够,则剩余空间不用,从下一个单元起存放该位段。

  (2)可以通过定义长度为0的位段的方式使下一位段从下一存储单元开始。

  (3)可以定义无名位段。

  (4)位段的长度不能大于存储单元的长度。

  (5)位段无地址,不能对位段进行取地址运算。

  (6)位段可以以%d,%o,%x格式输出。

  (7)位段若出现在表达式中,将被系统自动转换成整数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值