一、typedef简介
typedef的出现有着代码简化, 促进跨平台开发的目的。
typedef
行为有点像 #define
宏,用其实际类型替代同义字。
不同点: typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。
参考文档:《Typedef函数指针的用法》
二、typedef struct
第一种:结构体和指针分开定义
// 先定义结构体
struct Data {
int a;
int b;
int c;
};
// 再用 typedef 定义指针
typedef struct Data *PData;
第二种:合在一起简化代码:
typedef struct Data {
int a;
int b;
int c;
} Data, *PData ;
稍微说明一下:
typedef struct 本名 {
// ...
} 别名;
参考文档:《C语言中typedef的使用》
2.1 sizeof计算结构体类型长度
2.2 关于 error C2065: “Data”: 未声明的标识符
在声明结构体时,必须列出它包含的所有成员
语法结构 struct tag { member-list} variable-list;
#include <stdio.h>
/* 这里的Data是标签 类似于面包形状模板,它给定了制作出来的面包的形状,但是它没有制作出面包*/
struct Data {
int a;
int b;
int c;
};
/*利用上述的标签(面包模板),制作出一个面包(SIMPLE 类型的结构体)*/
struct Data DataX; // 注意:这里的 struct 不可以省略
int main() {
printf("%d\n", sizeof(DataX)); // 12
return 1;
}
struct Data DataX;
声明创建名为DataX的变量,它包含三个成员。
在 C 语言中,sizeof()
是一个判断数据类型或者表达式长度的运算符。
因此,你传“标签”Data
作为sizeof
的参数是不可行的,在上面这个例子中,你需要传“类型名” DataX
。
“标签”是可以省略的,如下图这样写是可以的:
参考文档:《struct结构体的多种声明方式》
2.3 “标签”怎么用?
那这个“标签”就“一无是处”,甚至“不可用”?
其实,也可以用“标签”来表示类型,只是用起来语法上比较“啰嗦”:
参考文档:《给结构体分配堆区内存》
2.4 最佳实践
结合来看,个人感觉这样写还不错:
typedef struct {
int a;
int b;
int c;
} Data, *PData;
三、关于c语言中new的使用
我们声明了一个PData
类型,它相当于Data*
类型。
现在我们想分配内存得到结构体变量,并且为结构体成员变量赋值,代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int a;
int b;
int c;
} Data, *PData;
int main() {
// 必须使用malloc函数,因为C语言没有new这个操作符
PData d = (PData)malloc(sizeof(Data)); // 相当于 Data* d = (Data*)malloc(sizeof(Data));
(*d).a = 1;
(*d).b = 2;
(*d).c = 3;
printf("0x%p", d);
return 1;
}
四、在栈上申请内存
前一节是在堆区申请内存,现在我们在栈区申请内存,并且为结构体成员变量赋值,代码如下:
#include <stdio.h>
typedef struct {
int a;
int b;
int c;
} Data, *PData;
int main() {
Data d;
d.a = 1;
d.b = 2;
d.c = 3;
printf("0x%p\n", &d);
printf("%d, %d, %d\n", d.a, d.b, d.c);
return 1;
}