(C/C++)结构体、枚举、宏、联合体、内联函数

结构体类型的定义和使用

这篇文章很详细,值得一看C语言结构体类型的定义和使用

结构体对齐问题

关于结构体对齐问题请阅读:结构体对齐规则及举例

系统指定类型的大小与系统有关,这里取

数据类型字节
char1
float4
double8
long double16
short int2
int4
long int8
long long int8
(1)按结构体最大成员对齐(32位机下double、long long按照4字节对齐)
案例一:
struct A{
	char a;
	short b;
	int a;	
};

结果是8

案例二:

struct A{
	int a;
	double b;
};

结果是12并非16

(2)结构体嵌套
嵌套的结构体会在先内部完成对齐。
案例一:

struct A{
	short a;
	char b;
};
struct B{
	struct A b;
	char c;
	int d;
};

结果是12,而非8
如果是:
案例二:

struct A{
	short a;
	char b;
	char c;
	int d;
};

则是8

(3)每个成员的起始位置必须是当前成员大小的整数倍
例如:

  • short的起始位置必须是2的倍数。
  • int、long long、double的起始位置必须是4的倍数。
  • char则随便放,因为是1。
struct A{	
	char a;
	short b;
	int c;
};

b的偏移是2而非1

(4)在使用预编译指令指定对齐方式之后,一切听预编译指令
#pragma pack(nbytes)可以指定按nbytes字节对齐。

枚举常量与宏的区别

  • 枚举常量属于常量,但宏不是常量;
  • 枚举常量具有类型,但宏没有类型,枚举变量具有与普通变量相同的诸如作用域、值等性质,但宏没有,宏不是语言的一部分,它是一种预处理替换符。枚举类型主要用于限制性输入,例如,某个函数的某参数只接受某种类型中的有限个数值,除此之外的其它数值都不接受,这时候枚举能很好地解决这个问题。能用枚举尽量用枚举,否则在调试的时候你是看不到当时的值的。
  • 枚举可以一次定义大量相关的常量,而#define 宏一次只能定义一个。

宏函数与普通函数对比

  • 优点:
    宏函数在预处理期间会进行宏替换,没有函数压栈开销,运行效率高。
  • 缺点:
    1、不安全(不会进行类型检测)
    2、代码复用率不高
    3、不停的进行替换,增长代码长度
    4、不能调试

内联函数

概念

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率

特性

  • inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的的函数不适宜使用内联
  • inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联
  • inline必须函数定义放在一起,才能成为内联函数,仅将inline放在声明前是不起作用的
  • 定义在类内的成员函数默认定义为内联函数

注意事项

在C++中,强制建议使用const代替宏常量,使用内联函数代替宏函数,const和内联函数在进行编译时不仅进行替换,而且还会进行参数类型检测,提高了程序的安全性。内敛函数可以是普通函数,也可以是类的成员函数;函数式宏不能作为类的成员函数

宏与内联函数的区别

  • 内联函数采用的是值传递,而宏定义采用的是对等替换.
  • 宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销
  • 编译器在调用一个内联函数时,会首先检查它的参数的类型,保证调用正确。然后进行一系列的相关检查,就像对待任何一个真正的函数一样。这样就消除了它的隐患和局限性。

注意事项

  • 在内联函数内不允许用循环语句和开关语句和递归。
  • 内联函数的定义必须出现在内联函数第一次被调用之前。

宏与const的区别

  • 用#define MAX 255定义的常量是没有类型的,所给出的是一个立即数,编译器只是把所定义的常量值与所定义的常量的名字联系起来,define所定义的宏变量在预处理的时候进行替换,在程序中使用到该常量的地方都要进行拷贝替换;
  • 用const float MAX = 255; 定义的常量有类型名字,存放在内存的静态区域中,在程序运行过程中const变量只有一个拷贝,而#define 所定义的宏变量却有多个拷贝,所以宏定义在程序运行过程中所消耗的内存要比const变量的大得多;
  • 用define定义的常量是不可以用指针变量去指向的,用const定义的常量是可以用指针去指向该常量的地址的;
  • 用define可以定义一些简单的函数,const是不可以定义函数的.

具体来说,有以下几方面的区别

  • 编译器处理方式
    define – 在预处理阶段进行替换
    const – 在编译时确定其值
  • 类型检查
    define – 无类型,不进行类型安全检查,可能会产生意想不到的错误
    const – 有数据类型,编译时会进行类型检查
  • 内存空间
    define – 不分配内存,给出的是立即数,有多少次使用就进行多少次替换,在内存中会有多个拷贝,消耗内存大
    const – 在静态存储区中分配空间,在程序运行过程中内存中只有一个拷贝
  • 其他
    1、在编译时, 编译器通常不为const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。
    2、宏替换只作替换,不做计算,不做表达式求解。
    3、宏定义的作用范围仅限于当前文件。
    4、默认状态下,const对象只在文件内有效,当多个文件中出现了同名的const变量时,等同于在不同文件中分别定义了独立的变量。 如果想在多个文件之间共享const对象,必须在变量定义之前添加extern关键字(在声明和定义时都要)。

联合体和结构体区别

  • 两者都可以有多个成员,结构体是多个不同类型变量的组合,其占用的内存大小是所有变量大小的总和; 联合体多个不同类型的变量占用一份存储空间,其占用内存的大小是联合体中最大的那个变量的大小。
  • 由于共用一份存储空间,所以对联合体的成员进行修改会顺带改变其他成员,结构体则不会。

C和C++结构体区别

  • C的结构体内不允许有函数成员存在,C++允许有内部成员函数。所以C的结构体是没有构造函数、析构函数、和this指针的。
  • C的结构体对内部成员变量的访问权限只能是public,而C++允许public,protected,private三种。
  • C语言的结构体是不可以继承的,C++的结构体是可以从其他的结构体或者类继承过来的。
  • 创建结构体对象的书写不同,C++直接用结构体名 变量名;而C要struct 结构体名 变量名;
  • C结构体不可以有static成员。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只嵌入式爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值