第十二章-typedef
- 作用:我们可以使用typedef关键字为各种数据类型定义一个新名字(别名)。
1 #include <stdio.h>
2
3 typedef int Integer;
4 typedef unsigned int UInterger;
6 typedef float Float;
7
8 int main(int argc, const char * argv[]) {
9 Integer i = -10;
10 UInterger ui = 11;
12 Float f = 12.39f;
14 printf("%d %d %.2f", i, ui, f);
16 return 0;
17 }
- 也可以在别名的基础上再起一个别名
typedef int Integer;
typedef Integer MyInteger;
typedef与数组
//定义一个整型数组包含100个元素
int a[100];
//用typedef取别名
typedef int Num[100];
Num a;
typedef与指针
- 除了可以给基本数据类型起别名,typedef也可以给指针起别名
1 #include <stdio.h>
3 typedef char * String;
5 int main(int argc, const char * argv[]) {
6 // 相当于char *str = "This is a string!";
7 String str = "This is a string!";
9 printf("%s", str);
11 return 0;
12 }
typedef与结构体
- 使用typedef给结构体起别名
1 // 定义一个结构体
2 struct MyPoint {
3 float x;
4 float y;
5 };
6
7 // 起别名
8 typedef struct MyPoint Point;
9
10 int main(int argc, const char * argv[]) {
11 // 定义结构体变量
12 Point p;
13 p.x = 10.0f;
14 p.y = 20.0f;
15
16 return 0;
17 }
其实第1~第8行的代码可以简写为:
// 定义一个结构体,顺便起别名
typedef struct MyPoint {
float x;
float y;
} Point;
甚至可以省略结构体名称:
typedef struct {
float x;
float y;
} Point;
- typedef与指向结构体的指针
- typedef可以给指针、结构体起别名,当然也可以给指向结构体的指针起别名
1 #include <stdio.h>
2
3 // 定义一个结构体并起别名
4 typedef struct {
5 float x;
6 float y;
7 } Point;
8
9 // 起别名
10 typedef Point * PP;
11
12 int main(int argc, const char * argv[]) {
13 // 定义结构体变量
14 Point point = {10, 20};
15
16 // 定义指针变量
17 PP p = &point;
18
19 // 利用指针变量访问结构体成员
20 printf("x=%f,y=%f", p->x, p->y);
21 return 0;
22 }
typedef与枚举类型
- 使用typedef给枚举类型起别名也可以使代码简洁。
1 // 定义枚举类型
2 enum Season {spring, summer, autumn, winter};
3 // 给枚举类型起别名
4 typedef enum Season Season;
5
6 int main(int argc, const char * argv[]) {
7 // 定义枚举变量
8 Season s = spring;
9
10 return 0;
11 }
第1行~第4行代码可以简化为:
// 定义枚举类型,并且起别名
typedef enum Season {spring, summer, autumn, winter} Season
甚至可以省略枚举名称,简化为:
typedef enum {spring, summer, autumn, winter} Season;
typedef与指向函数的指针
1 #include <stdio.h>
2
3 // 定义一个sum函数,计算a跟b的和
4 int sum(int a, int b) {
5 int c = a + b;
6 printf("%d + %d = %d", a, b, c);
7 return c;
8 }
9
10 typedef int (*MySum)(int, int);
11
12 int main(int argc, const char * argv[]) {
13 // 定义一个指向sum函数的指针变量p
14 MySum p = sum;
15
16 // 利用指针变量p调用sum函数
17 (*p)(4, 5);
18
19 return 0;
20 }
typedef与#define区别
#define
是在预编译时处理的,它只能做简单的字符串替换,而typedef是在编译阶段处理的.- 先来看看下面的两段代码有什么区别
第一段
1 typedef char *String;
2
3 int main(int argc, const char * argv[]) {
4 String str = "This is a string!";
5 return 0;
6 }
第二段:
1 #define String char *
2
3 int main(int argc, const char * argv[]) {
4 String str = "This is a string!";
5 return 0;
6 }
上面的两段代码只是第1行代码不一样,运行的效果都是一样的
但它们的实现方式是不一样的:
第1段代码是用typedef给char *定义别名为String
第2段代码是用char *代替代码中的宏名String
第三段:
1 typedef char *String1;
2
3 #define String2 char *
4
5 int main(int argc, const char * argv[]) {
6 String1 str1, str2;
7
8 String2 str3, str4;
9 return 0;
10 }
注意:在这种情况下,只有str1、str2、str3才是指向char类型的指针变量,str4只是个char类型的变量。
原因:
typedef char *String1;
String1 str1, str2;
经过typedef处理后,String1也算是一种数据类型,所以第3行代码相当于
String1 str1;
String1 str2;
由于String1就是char *,所以上面的两行代码等于
char *str1;
char *str2;
再看看宏定义的情况
#define String2 char *
String2 str3, str4;
因为宏定义纯粹是字符串替换,用char *代替String2,所以第3行代码相当于
char * str3, str4;
其实也就相当于:
char * str3;
char str4;
- 重定义数组,#define就做不到
//定义一个整型数组包含100个元素
int a[100];
//用typedef取别名
typedef int Num[100];
Num a;
总结
- 用typedef声明一个新的类型名的方法是:
- 先按定义变量(可不是定义类型)的方法写出定义体(如:
int i;
) - 将变量名换成新的类型名(如:将i 换成Count)
- 在最前面加上typedef(如: typedef int Count)即可
- 然后就可以用新的类型名定义变量了
- 先按定义变量(可不是定义类型)的方法写出定义体(如:
- 一句话:按定义变量的方式,把变量名换上新的类型名,并且在最前面加上”typedef”,就声明了新类型代表原来的类型;
- 习惯上重新命名的类型名首字母要大写,以便于与系统提供的标准类型标识符区别
- 举例:
1.先按定义数组变量的形式书写: int a[100];
2.将变量a换成自己命名的类型名:int Num[100];
3.在前面加上typedef得到: typedef int Num[100];
4.用来定义变量
num a;
相当于定义了
int a[100];