目录
1. 什么是typedef
typedef是 C 和 C++ 语言中的一个关键字,用于为已有的数据类型定义新的名称(别名)。它的主要作用是增强代码的可读性和可维护性,使得程序员可以更方便地使用复杂数据类型或者简化长类型名的书写。
简化复杂类型名称: 使用typedef可以将复杂的类型名简化为一个更简单的别名,提高代码的可读性。
跨平台开发: 在跨平台开发中,typedef可以帮助隐藏不同平台下的类型差异,提高代码的可移植性。
模块化设计: 有助于将数据类型的定义和使用分离开来,使程序更易于维护和修改。
2. typedef的用法
2.1 对于数据类型的重定义
使用 typedef 定义类型名后,原类型名作用不变,我们可以通过typedef对基本数据而理性进行重定义例如:
typedef int i;
typedef char ch;
typedef long long int lli;
这样我们在后续使用这些数据类型时可以这样写:
i a = 5;
lli b = 10;
ch c = 'a';
他们等价于:
int a = 5;
long long int b = 10;
char c = 'a';
2.2 对于函数的重定义
typedef定义了OperationFunc类型,它表示一个函数指针,可以指向接受两个整数参数并返回整数的函数。这样,使用OperationFunc类型来声明函数指针变量op,可以避免每次声明函数指针时都需要写出完整的指针语法:
#include <stdio.h>
// 定义一个函数指针类型,用 typedef 简化声明
typedef int (*OperationFunc)(int, int);
// 定义两个函数,用于加法和乘法
int add(int a, int b) {
return a + b;
}
int multiply(int a, int b) {
return a * b;
}
int main() {
int result;
OperationFunc op; // 使用 typedef 后的函数指针类型
op = add; // 将函数指针指向加法函数
result = op(3, 4); // 调用加法函数
printf("3 + 4 = %d\n", result);
op = multiply; // 将函数指针指向乘法函数
result = op(3, 4); // 调用乘法函数
printf("3 * 4 = %d\n", result);
return 0;
}
注意,typedef并不用于定义函数本身,而是用于定义类型别名,包括指向函数的指针类型。因此,你不能使用typedef来为函数本身提供别名,例如这样是不合法的:
typedef int myFunction(int); // 错误,不能给函数本身起别名
2.3 对于指针的重定义
typedef int* PTRINT;
以上就是给int* 起了一个新的名字PTRINT。可定义int类型指针变量如:
PTRINT x;
其等价于:
int* x
实际代码使用:
#include<stdio.h>
typedef int* PTRINT;
int main()
{
int a = 0;
PTRINT b = &a;
int* c = &a;
printf("a:%d\na:%p\n", a, &a);
printf("b:%d\nb:%p\n", *b, b);
printf("c:%d\nc:%p\n", *c, c);
return 0;
}
可以看到b和c无论是值还是地址都是一样的。
2.4 对于数组指针的重定义
#include <stdio.h>
// 假设我们有一个二维整数数组
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// 使用 typedef 定义一个二维整数数组指针类型
typedef int (*MatrixPtr)[4];
int main() {
MatrixPtr ptr; // 使用 typedef 后的数组指针类型
ptr = matrix; // 将指针指向二维数组的第一个元素
// 访问数组元素示例
printf("matrix[1][2] = %d\n", ptr[1][2]); // 输出 7
return 0;
}
2.5 对于指针数组的重定义
#include<stdio.h>
typedef int* i[5];
int main()
{
int a = 10, b = 20, c = 30;
i arr = { &a,&b,&c };
printf("%d\n", **arr);
printf("%d\n", **(arr + 1));
printf("%d\n", **(arr + 2));
return 0;
}
2.6 对于结构体的重定义(typedef struct)
在声明结构体时可为结构体和结构体指针起别名,如:
struct LNode{
ElemType data;
struct LNode *next;
};
typedef struct LNode LNode;
typedef struct LNode *LinkList;
其表述方式不唯一,也可以写为:
struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
上述两种方式在实际使用过程中:
LNode *next;
//等价于
LinkList next;
下面我们可以实际使用对比一下:
2.6.1 对结构体起别名
#include <stdio.h>
struct student
{
char name[20];
int age;
char sex[7];
int* score; // 例子:添加一个指向整数的指针成员
};
typedef struct student stu;
int main()
{
int score_value = 85;
struct student a = { "wang", 10, "male", &score_value }; // 初始化包含指针成员的结构体
stu b = { "wang", 10, "male", &score_value }; // 初始化包含指针成员的结构体
printf("struct student的年龄:%d\n", a.age);
printf("struct student的成绩: %d\n", *(a.score)); // 访问指针成员并输出其值
printf("stu的年龄:%d\n", b.age);
printf("stu的成绩: %d\n", *(b.score)); // 访问指针成员并输出其值
return 0;
}
在这里我们对结构体 struct student 重定义为stu ,并通过 stu 声明变量 a 并进行初始化,可以发现其中struct student结构体修饰的a,与typedef重命名后的stu所表达的意思是一样的:
2.6.2 对结构体指针起别名
#include <stdio.h>
struct student
{
char name[20];
int age;
char sex[7];
int* score; // 例子:添加一个指向整数的指针成员
};
typedef struct student* pdata;
int main()
{
int score_value = 85;
struct student a = { "wang", 10, "male", &score_value }; // 初始化包含指针成员的结构体
struct student* ptr;
ptr = &a;
//也可以写为 struct student* ptr= &a;
printf("ptr学生姓名:%s\n", ptr->name);
printf("ptr学生年龄:%d\n", ptr->age);
printf("ptr学生性别:%s\n", ptr->sex);
printf("ptr学生成绩:%d\n", *(ptr->score));
pdata pd;
pd = &a;
printf("pd学生姓名:%s\n", pd->name);
printf("pd学生年龄:%d\n", pd->age);
printf("pd学生性别:%s\n", pd->sex);
printf("pd学生成绩:%d\n", *(pd->score));
return 0;
}
这里可以使用箭头操作符 -> 访问结构体指针所指向的成员,发现也能正常取值:
2.6.3 汇总
代码一:
#include <stdio.h>
struct student
{
char name[20];
int age;
char sex[7];
int* score; // 例子:添加一个指向整数的指针成员
};
typedef struct student stu;
typedef struct student* pdata;
int main()
{
int score_value = 85;
struct student a = { "wang", 10, "male", &score_value }; // 初始化包含指针成员的结构体
stu b = { "wang", 10, "male", &score_value }; // 初始化包含指针成员的结构体
printf("struct student的年龄:%d\n", a.age);
printf("struct student的成绩: %d\n", *(a.score)); // 访问指针成员并输出其值
printf("stu的年龄:%d\n", b.age);
printf("stu的成绩: %d\n", *(b.score)); // 访问指针成员并输出其值
struct student* ptr;
ptr = &a;
//也可以写为 struct student* ptr= &a;
printf("ptr学生姓名:%s\n", ptr->name);
printf("ptr学生年龄:%d\n", ptr->age);
printf("ptr学生性别:%s\n", ptr->sex);
printf("ptr学生成绩:%d\n", *(ptr->score));
pdata pd;
pd = &a;
printf("pd学生姓名:%s\n", pd->name);
printf("pd学生年龄:%d\n", pd->age);
printf("pd学生性别:%s\n", pd->sex);
printf("pd学生成绩:%d\n", *(pd->score));
return 0;
}
代码二:
上文我们也提到了:
struct LNode{
ElemType data;
struct LNode *next;
};
typedef struct LNode LNode;
typedef struct LNode *LinkList;
等价于:
struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
那么我们可以更改代码为:
#include <stdio.h>
typedef struct student
{
char name[20];
int age;
char sex[7];
int* score; // 例子:添加一个指向整数的指针成员
}stu, * pdata;
int main()
{
int score_value = 85;
struct student a = { "wang", 10, "male", &score_value }; // 初始化包含指针成员的结构体
stu b = { "wang", 10, "male", &score_value }; // 初始化包含指针成员的结构体
printf("struct student的年龄:%d\n", a.age);
printf("struct student的成绩: %d\n", *(a.score)); // 访问指针成员并输出其值
printf("stu的年龄:%d\n", b.age);
printf("stu的成绩: %d\n", *(b.score)); // 访问指针成员并输出其值
struct student* ptr;
ptr = &a;
//也可以写为 struct student* ptr= &a;
printf("ptr学生姓名:%s\n", ptr->name);
printf("ptr学生年龄:%d\n", ptr->age);
printf("ptr学生性别:%s\n", ptr->sex);
printf("ptr学生成绩:%d\n", *(ptr->score));
pdata pd;
pd = &a;
printf("pd学生姓名:%s\n", pd->name);
printf("pd学生年龄:%d\n", pd->age);
printf("pd学生性别:%s\n", pd->sex);
printf("pd学生成绩:%d\n", *(pd->score));
return 0;
}
可以发现值并未发生改变:
2.7 对于共用体的重定义(typedef union)
用法与结构体类似,我们对共用体 union un 重定义为 u ,并通过 u 声明变量共用体变量 b 并进行初始化。
#include<stdio.h>
union un
{
char a;
int b;
};
typedef union un u;
int main()
{
u b = { 0 };
b.a = 'a';
printf("%d", b.b);
return 0;
}
也可以将其写为:
#include<stdio.h>
typedef union un
{
char a;
int b;
}u;
int main()
{
u b = { 0 };
b.a = 'a';
printf("%d", b.b);
return 0;
}
2.8 对于枚举变量的重定义(typedef enum)
使用方法也可结构体类似,具体可以参考结构体的用法,下面是个简单的例子:
#include<stdio.h>
enum week
{
one = 1,
two,
three,
four,
five,
six,
seven
};
typedef enum week w;
int main()
{
w a = one;
printf("%d", a);
return 0;
}
也可以写为:
#include<stdio.h>
typedef enum week
{
one = 1,
two,
three,
four,
five,
six,
seven
}w;
int main()
{
w a = one;
printf("%d", a);
return 0;
}