這講介紹C語言中很經常使用的一個關鍵字---typedef。html
* 咱們可使用typedef關鍵字爲各類數據類型定義一個新名字(別名)。ios
#include <stdio.h> typedef int Integer; typedef unsigned int UInterger; typedef float Float; int main(int argc, const char * argv[]) { Integer i = -10; UInterger ui = 11; Float f = 12.39f; printf("%d %d %.2f", i, ui, f); return 0; }
在第三、第四、第6行分別給int、unsigned int、float起了個別名,而後在main函數中使用別名定義變量,用來跟原來的基本類型是徹底同樣的。輸出結果:spring
固然,給類型起別名後,原來的int、float仍是能夠正常使用的:函數
int i = 10; float f = 10.0f;
* 也能夠在別名的基礎上再起一個別名ui
typedef int Integer; typedef Integer MyInteger;
除開能夠給基本數據類型起別名,typedef也能夠給指針起別名spa
#include <stdio.h> typedef char *String; int main(int argc, const char * argv[]) { // 至關於char *str = "This is a string!"; String str = "This is a string!"; printf("%s", str); return 0; }
在第3給指針類型char *起別名爲String,而後在第7行使用String定義了一個字符串,是否是有點Java的感受?指針
給結構體起別名可使代碼更加簡潔明code
// 定義一個結構體 struct MyPoint{ float x; float y; }; int main(int argc, const char *arg[]){ // 定義結構體的變量 struct MyPoint p; p.x = 10.0f; p.y = 20.2f; return 0; }
默認狀況下,咱們定義結構體變量須要帶個struct關鍵字,看第9行orm
// 定義一個結構體 struct MyPoint { float x; float y; }; // 起別名 typedef struct MyPoint Point; int main(int argc, const char * argv[]) { // 定義結構體變量 Point p; p.x = 10.0f; p.y = 20.0f; return 0; }
咱們在第8行給結構體MyPoint起了個別名叫作Point,而後在12行使用Point定義了一個結構體變量p,不用再帶上struct關鍵字了htm
其實第1~第8行的代碼能夠簡寫爲:
// 定義一個結構體,順便起別名 typedef struct MyPoint { float x; float y; } Point;
甚至能夠省略結構體名稱:
typedef struct { float x; float y; } Point;
typedef能夠給指針、結構體起別名,固然也能夠給指向結構體的指針起別名
#include <stdio.h> // 定義一個結構體並起別名 typedef struct { float x; float y; } Point; // 起別名 typedef Point *PP; int main(int argc, const char * argv[]) { // 定義結構體變量 Point point = {10, 20}; // 定義指針變量 PP p = &point; // 利用指針變量訪問結構體成員 printf("x=%f,y=%f", p->x, p->y); return 0; }
在第4行定義了一個結構體,順便起了個別名叫Point,第10行爲指向結構體的指針定義了別名PP。而後在main函數中使用這2個別名。
輸出結果:
使用typedef給枚舉類型起別名也可使代碼簡潔。
// 定義枚舉類型 enum Season {spring, summer, autumn, winter}; // 給枚舉類型起別名 typedef enum Season Season; int main(int argc, const char * argv[]) { // 定義枚舉變量 Season s = spring; return 0; }
在第2行定義了枚舉類型,在第4行起了別名爲Season,而後在第8行直接使用別名定義枚舉變量,不用再帶上enum關鍵字了。
第1行~第4行代碼能夠簡化爲:
// 定義枚舉類型,而且起別名typedef enum Season {spring, summer, autumn, winter} Season
甚至能夠省略枚舉名稱,簡化爲:
typedef enum {spring, summer, autumn, winter} Season;
1.先來回顧下函數指針的知識
#include <stdio.h> // 定義一個sum函數,計算a跟b的和 int sum(int a, int b) { int c = a + b; printf("%d + %d = %d", a, b, c); return c; } int main(int argc, const char * argv[]) { // 定義一個指向sum函數的指針變量p int (*p)(int, int) = sum; // 利用指針變量p調用sum函數 (*p)(4, 5); return 0; }
在第4行定義了一個sum函數,第12行定義了一個指向sum函數的指針變量p,能夠發現,這個指針變量p的定義比通常的指針變量看來複雜多了,不利於理解。
* 第15行調用了p指向的sum函數,輸出結果:
2.爲了簡化代碼和方便理解,咱們可使用typedef給指向函數的指針類型起別名
#include <stdio.h> // 定義一個sum函數,計算a跟b的和 int sum(int a, int b) { int c = a + b; printf("%d + %d = %d", a, b, c); return c; } typedef int (*MySum)(int, int); int main(int argc, const char * argv[]) { // 定義一個指向sum函數的指針變量p MySum p = sum; // 利用指針變量p調用sum函數 (*p)(4, 5); return 0; }
* 看第10行,意思是:給指向函數的指針類型,起了個別名叫MySum,被指向的函數接收2個int類型的參數,返回值爲int類型。
* 在第14行直接用別名MySum定義一個指向sum函數的指針變量p,這樣看起來簡單舒服多了。第17行的函數調用是同樣的。
1.先來看看下面的兩段代碼有什麼區別(注意每一段的第1行代碼)
* 第1段
typedef char *String; int main(int argc, const char * argv[]) { String str = "This is a string!"; return 0; }
#define String char * int main(int argc, const char * argv[]) { String str = "This is a string!"; return 0; }
上面的兩段代碼只是第1行代碼不同,運行的效果都是同樣的:定義了一個字符串"This is a string!"。
但它們的實現方式是不同的:
第1段代碼是用typedef給char *定義別名爲String
第2段代碼是用char *代替代碼中的宏名String
只看上面兩段代碼,彷佛看不太出typedef和#define的區別。
2.再來看一段代碼
typedef char *String1; #define String2 char * int main(int argc, const char * argv[]) { String1 str1, str2; String2 str3, str4; return 0; }
第1行給char *起了個別名String1,第2行定義了宏String2。而後在第六、第8行定義了4個變量。
重點來了,注意:在這種狀況下,只有str一、str二、str3纔是指向char類型的指針變量,str4只是個char類型的變量。
下面簡單分析一下緣由:
* 若是連續聲明兩個int類型的變量,咱們能夠這樣寫:
int a, b;
上面的代碼至關於:
int a;int b;
* 以此類推
1 typedef char *String1;2 3 String1 str1, str2;
通過typedef處理後,String1也算是一種數據類型,因此第3行代碼至關於
1 String1 str1;2 String1 str2;
因爲String1就是char *,因此上面的兩行代碼等於
char *str1;char *str2;
* 再看看宏定義的狀況
1 #define String2 char *2 3 String2 str3, str4;
由於宏定義純粹是字符串替換,用char *代替String2,因此第3行代碼至關於
char * str3, str4;
其實也就至關於:
char * str3;char str4;
能夠看出,只有str4是基本數據類型,str一、str二、str3都是指針類型。
因此,之後給類型起別名,最好使用typedef,而不是使用#define
注:本文轉自M了個J的博客。