typedef是在计算机编程语言中用来为复杂的声明定义简单的别名,它与宏定义有些差异。
它本身是一种存储类的关键字,与auto、extern、mutable、static、register等关键字不能出现在同一个表达式中。
(1)typedef 的声明
typedef 数据类型 别名;
(2)为基本数据类型定义新的类型名
演示代码如下:
#include <iostream>
typedef long long INT_64;
using namespace std;
int main()
{
INT_64 a = 3;
cout << sizeof(a) << endl;
return 0;
}
数据类型 long long 占用8个字节(64位),使用 INT_64 替换 long long 可以一目了然的知道 a 占用8个字节。
在标准库 stdint 中,已经定义了各种整数类型:
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
用于区分该整数占用几个字节,在实际开发中,可以直接使用标准库中的类型:int8_t、int16_t、int32_t、int64_t,其中int8_t占用1个字节,int16_t占用2个字节,int32_t占用4个字节,int64_t占用8个字节。
我们还可以定义我们还可以使用这种方法来定义与平台无关的类型。比如,要定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型,即:
typedef long double REAL;
在不支持 long double 的平台二上,改为:
typedef double REAL;
甚至还可以在连 double 都不支持的平台三上,改为:
typedef float REAL;
这样,当跨平台移植程序时,我们只需要修改一下 typedef 的定义即可,而不用对其他源代码做任何修改。
(3)为自定义数据类型(结构体、共用体和枚举类型)定义简洁的类型名称
以结构体为例,演示代码如下:
struct Point
{
double x;
double y;
double z;
};
int main()
{
struct Point point = { 10.0, 9.0, 0 };
return 0;
}
在旧的C语言,定义 point 变量必须添加 struct 关键字,为了简化类型名称,使用 typedef 定义新的结构体类型:
struct XPoint
{
double x;
double y;
double z;
};
typedef struct XPoint Point;
int main()
{
Point point = { 10.0, 9.0, 0 };
return 0;
}
还可以将 typedef 放在 struct 前面做进一步简化。
typedef struct Point
{
double x;
double y;
double z;
};
int main()
{
Point point = { 10.0, 9.0, 0 };
return 0;
}
(4)为数组定义简洁的类型名称
演示代码如下:
typedef int INT_ARRAY_10[10];
int main()
{
INT_ARRAY_10 arr = {1, 2, 3, 4, 5};
for (size_t i = 0; i < 5; i++)
{
cout << arr[i] << endl;
}
return 0;
}
(5)为指针定义简洁的名称
[简单指针]
演示代码如下:
#include <iostream>
#include <string>
using namespace std;
typedef char* PCHAR;
int main()
{
PCHAR pa;
char a[] = "zhangsan";
pa = a;
for (size_t i = 0; i < strlen(a); i++)
{
cout << *pa++ << endl;
}
return 0;
}
[复杂指针]
假设有一个指向函数的指针,代码如下:
#include <iostream>
#include <string>
using namespace std;
int sum(int a, int b);
int main()
{
int (*p)(int, int) = sum;
int result = (*p)(3, 4);
cout << result << endl;
return 0;
}
int sum(int a, int b)
{
return a + b;
}
我们认为 int (*p)(int, int) 是比较复杂的,需要使用 typedef 来简化,简化后的代码是:
#include <iostream>
#include <string>
using namespace std;
int sum(int a, int b);
typedef int (*P)(int, int);
int main()
{
P p = sum;
int result = p(3, 4);
cout << result << endl;
return 0;
}
int sum(int a, int b)
{
return a + b;
}
这样就将
int (*p)(int, int) = sum;
简化成了
P p = sum;
(6)typedef的陷阱
接下来看一个简单的 typedef 使用示例,如下面的代码所示:
typedef char* PCHAR;
int strcmp(const PCHAR,const PCHAR);
在上面的代码中,“const PCHAR” 是否相当于 “const char*” 呢?
答案是否定的,原因很简单,typedef 是用来定义一种类型的新别名的,它不同于宏,不是简单的字符串替换。
因此,const PCHAR
中的 const 给予了整个指针本身常量性,也就是形成了常量指针char* const(一个指向char的常量指针)
。
即它实际上相当于char* const
,而不是 const char*(指向常量 char 的指针)
。当然,要想让 const PCHAR 相当于 const char* 也很容易,如下面的代码所示:
typedef const char* PCHAR;
int strcmp(PCHAR, PCHAR);
其实,无论什么时候,只要为指针声明 typedef,那么就应该在最终的 typedef 名称中加一个 const,以使得该指针本身是常量。
还需要特别注意的是,虽然 typedef 并不真正影响对象的存储特性,但在语法上它还是一个存储类的关键字,就像 auto、extern、static 和 register 等关键字一样。因此,像下面这种声明方式是不可行的:
typedef static int INT_STATIC;
不可行的原因是不能声明多个存储类关键字,由于 typedef 已经占据了存储类关键字的位置,因此,在 typedef 声明中就不能够再使用 static 或任何其他存储类关键字了。当然,编译器也会报错,如在 VC++2010 中的报错信息为“无法指定多个存储类”。
[本章完...]
网友评论