typedef
typedef 用来声明一个新类型名,用新的类型来替换一个已经存在的类型,方便移植。
typedef 现有类型 新类型名 ;
=> 新类型名 就和 现有的类型 是一样
如:
typedef unsigned char uint_8;
uint_8 a;
<=> unsigned char a;
typedef struct student
{
int num;
int age;
char name[32];
} STU; //结构体类型名
STU==struct student
typedef void func_type(int , char);
定义了一个没有返回值,并且带有一个int和一个char类型参数的函数类型。这个函数类型名是func_type,也就是说可以用func_type替代这个函数类型.
typedef 总结:
typedef 加在定义的对象(变量、函数、指针)的前面,定义对象名,就变成了一个新的类型名
#define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用,而typedef有自己的作用域。
注:
#define和typedef的区别
#define MMM struct s*
typedef struct s* NNN;
MMM p1, p2;
//struct s* p1, p2;
//用define定义 *跟p1跑了,所以p2没有*
NNN p3, p4;
//(struct s*) p3, p4;
p1 -> struct s* 类型的指针变量
p2 -> struct s 类型结构体变量
p3 -> struct s* 类型的指针变量
p4 -> struct s* 类型的指针变量
字节对齐的问题
CPU底层为了访问的效率出发,一般会要求,任何对象的地址必须是对齐的。
自然对齐:
数据地址是数据长度的倍数
n-字节对齐:
地址是n的倍数(n一般为2的x次幂)
结构体的每个成员通常会有一个默认的对齐方式,成员变量
将按照(除非程序员有其他的对齐的要求)默认的对齐方式是: 自然对齐
struct test
{
char a; //a的地址必须是1的倍数
int b; //b的地址必须是4的倍数
};
struct test t;
sizeof(t) == ? 8
a _ _ _
b b b b
在64bits ,编译器(GNU) :
char -> 一字节对齐
short -> 二字节对齐
int -> 4字节对齐
long -> 8字节对齐
long long -> 8字节对齐
float -> 4字节对齐
double -> 8字节对齐
long double -> 16字节对齐
pointer 指针类型 -> 8字节对齐
…
对于结构体,按最大的原始类型的对齐方式对齐!
struct MixedData
{
char D1;
short D2;
int D3;
char D4;
};
struct test
{
char s;
struct MixedData M;
};
sizeof(struct test) == ? 16
s _ _ _
D1 D2 D2 _
D3 D3 D3 D3
D4 _ _ _