Typedef

在C和C++程式语言中，codice_1是一个关键字。它用来对一个资料类型取一个别名，目的是为了使原始码更易于阅读和理解。它通常用于简化宣告复杂的类型组成的结构 ，但它也常常在各种长度的整数资料型别中看到，例如codice_2和codice_3。
语法.
codice_1的语法是 : codice_5
创建 codice_6 作为 codice_7 的别名 : <syntaxhighlight lang="c++">typedef int Length;</syntaxhighlight>创建 codice_8 作为一个指向「一个拥有两个 codice_9 当作参数并回传 codice_7 的函式」的指标的别名<syntaxhighlight lang="c++">typedef int (*PFI)(char *, char *);</syntaxhighlight>
使用范例.
创建一个具有特别意义的资料型别.
codice_1会被用来指定一种资料型别的意义。
例如 : 以下示范一个普通的宣告，速度及分数都被宣告为codice_7
<syntaxhighlight lang="c++">
int current_speed ; 
int high_score ; 
void congratulate(int your_score) 
</syntaxhighlight>通过codice_1来指定新的资料型别的意义:<syntaxhighlight lang="c++">
typedef int km_per_hour ;
typedef int points ;
km_per_hour current_speed ; //"km_per_hour" is synonymous with "int" here,
points high_score ; //and thus, the compiler treats our new variables as integers.
void congratulate(points your_score) {
</syntaxhighlight>前面两段程式码运作状况一样，但是使用codice_1的第二段程式码更清楚的表示了两个变数(score和speed)，虽然资料型别都是codice_7，却是各自代表不同的意义，且他们的资料并不相容。
但请注意，其清楚的表示不同意义只是对于工程师而言，C/C++的编译器认为两个变数都是codice_7时，并不会显示警告或错误，如: 以下程式码，使用宣告为速度的变数作为codice_17函式的参数 : <syntaxhighlight lang="c++">
void foo() 
</syntaxhighlight>
但是，虽然在上面的程式码中，编译器认为"km_per_hour"等于codice_7，但在使用前缀 codice_19, codice_20, codice_21时，两者并不能互换使用。<syntaxhighlight lang="c++">
void foo() {
</syntaxhighlight>
另一个例子：
<syntaxhighlight lang="c">
int coxes;
int jaffa;
coxes++;
if (jaffa == 10)
</syntaxhighlight>
现在来看以下程式码：
typedef int Apple;
typedef int Orange;
Apple coxes;
Orange jaffa;
coxes++;
if (jaffa == 10)
</syntaxhighlight>
这两段程式码都做同样的一件事。第二个例子使用了 codice_1，使其更易于了解将要进行什么。也就是一个变数包含关于苹果的资讯，而另一个包含关于橘子的资讯。
简化宣告语法.
struct var {
</syntaxhighlight>
此处使用者定义一个资料类型 "codice_23"。
像这样建立一个 "codice_23" 类型的变数，程式码必须写为（注意，在 C++ 中宣告一个 codice_25 时，同时也隐含了 codice_1，C 则没有）：
<syntaxhighlight lang="c">
struct var a;
</syntaxhighlight>
在例子的最末处加入一行语句：
typedef struct var newtype;
</syntaxhighlight>
现在要建立类型 "codice_23" 的变数时，程式码可以写为：
<syntaxhighlight lang="c">
newtype a;
</syntaxhighlight>
这样就更容易阅读了，因为不用再为每一个 "var" 类型的变数加上关键字 "codice_25"。
也可以给阵列使用 codice_1 宣告。<syntaxhighlight lang="c++">
typedef BaseType NewType ;
</syntaxhighlight>这样就可以在宣告一个 "codice_30" 类型和 "codice_31" 大小的新阵列时，将程式码写为：<syntaxhighlight lang="c++">
NewType array;
</syntaxhighlight>
与阵列一起使用.
codice_1可以简单的跟阵列一起使用。例如 : <syntaxhighlight lang="c++">
typedef char arrType; // type name: arrType
arrType *pArr; // same as: char (*pArr);
</syntaxhighlight>在这里，codice_33是codice_34则表示codice_35是一个指向储存codice_36型别记忆体的指标。
与指标一起使用.
可以使用typedef来定义一个新的指标型别 : <syntaxhighlight lang="c++">
typedef int *intptr; // type name: intptr
intptr ptr; // same as: int *ptr
</syntaxhighlight>在上面那段程式码中，codice_37是一个 指标型态codice_38的 新的别名。codice_39宣告了一个变数(codice_40)，其资料型别是codice_38。如此一来codice_40就是一个 可以指向一段储存codice_7资料的记忆体 的指标了。
使用codice_1来定义一个新的指标型别有时候会造成一些困惑 : <syntaxhighlight lang="c++">
typedef int *intptr;
intptr cliff, allen; // both cliff and allen are int* type
intptr cliff2, *allen2; // cliff2 is int* type, but allen2 is int** type
</syntaxhighlight>在上面的程式码中,"codice_45"表示宣告两个变数，其资料型别是codice_38，而codice_47则使codice_48的型别成为codice_49
与结构指标一起使用.
codice_50可以跟结构体指标一起使用。如下 : <syntaxhighlight lang="c++">
struct Node {
};
</syntaxhighlight>使用codice_1可以改写成如下 : <syntaxhighlight lang="c++">
typedef struct Node Node;
struct Node {
};
</syntaxhighlight>在C语言中，可以在一行中宣告复数的变数，不管其是不是指标。不管如何，如果你要宣告指标，必须在每个变数前面加上星号。
在下面的程式码中，工程师可能会以为codice_52是一个指标，这个可能会引起一些错误。<syntaxhighlight lang="c++">
struct Node *startptr, *endptr, *curptr, *prevptr, errptr, *refptr;
</syntaxhighlight>如果你用codice_1定义一个codice_54，这可以保证所有的变数都是一个指向一个codice_55的指标。<syntaxhighlight lang="c++">
typedef struct Node* NodePtr;
NodePtr startptr, endptr, curptr, prevptr, errptr, refptr;
</syntaxhighlight>
与函式指标一起使用.
先看看以下这段尚未使用codice_1的程式码：<syntaxhighlight lang="c++">
int do_math(float arg1, int arg2) {
int call_a_func(int (*call_this)(float, int)) {
int final_result = call_a_func(&do_math);
</syntaxhighlight>这段程式码可以被改写成如下：<syntaxhighlight lang="c++">
typedef int (*MathFunc)(float, int);
int do_math(float arg1, int arg2) {
int call_a_func(MathFunc call_this) {
int final_result = call_a_func(&do_math);
</syntaxhighlight>在这里，codice_57是一个指标，指向一个回传codice_7并以一个codice_59和一个codice_7作为参数使用的函式。当一个函式被当作参数使用时，如果少了codice_1它可能会变得难以了解。
以下是codice_62(来自FreeBSD)的函数原型：<syntaxhighlight lang="c++">
void (*signal(int sig, void (*func)(int)))(int);
</syntaxhighlight>上面宣告的函式相当的神秘，因为它没有清楚的显示它以什么函式当作参数，或回传了什么资料型别。一个初心者工程师甚至可能以为它接收一个codice_7作为参数，并不回传任何东西。但它其实接收了一个codice_7和一个codice_65作为参数，并回传了一个codice_65。它可以被改写成以下程式码：<syntaxhighlight lang="c++">
typedef void (*sighandler_t)(int);
sighandler_t signal(int sig, sighandler_t func);
</syntaxhighlight>
用来型别转换.
codice_1同时可以用来类型转换。例如：<syntaxhighlight lang="c++">
typedef int (*funcptr)(double); // pointer to function taking a double returning int
funcptr x = (funcptr) NULL; // C or C++
funcptr y = funcptr(NULL); // C++ only
funcptr z = static_cast<funcptr>(NULL); // C++ only
</syntaxhighlight>左侧，codice_68用来宣告变数；右侧，codice_68则用来转换值的型态。
如果少了codice_1，替换使用宣告语法和型别转换语法是几乎不能做到的。例如：<syntaxhighlight lang="c++">
void *p = NULL;
int (*x)(double) = (int (*)(double)) p; // This is legal
int (*)(double) y = (int (*)(double)) p; // Left-hand side is not legal
int (*z)(double) = (int (*p)(double)); // Right-hand side is not legal
</syntaxhighlight>