typedef用法总结
来源:互联网 发布:淘宝客微信小程序效果 编辑:程序博客网 时间:2024/06/17 09:04
1、问题引入:
接触了typedef多时,对它的了解是:用来声明一个别名,typedef后面的语法,是一个声明。
其实,他同define的差别是比较大的,不仅仅是替换问题。
如下
typedef int a[10]; typedef void (*p)(void)
typedef int Fun() ;
用上面的概念能解释了吗?是用a[10]来代替Int吗?答案是NO!
2、别人的解释:
typedef int Fun() ;
定义了一个函数类型Fun,所有这个类型的函数都返回一个int类型的值。
举个例子,假定有两个分别计算加和减的函数
int sum(int a, int b)
{
return (a + b);
}
int sub(int a, int b)
{
return (a - b);
}
typedef int CalcType(int a, int b); //这样CalcType就成了返回值为int型,接受参数为两个整
//数的函数。
int main()
{
int select = -1;
int result;
int a;
int b;
CalcType calculate[] = {sum, sub}; //留意。
printf("Please select calculation type\n");
scanf("%d\n", select);
printf("Input two value\n");
scanf("%d %d\n", &a, &b);
if (select == 0 || select == 1)
result = calculate[select](a, b);
return (0);
}
3、我的理解
1)举个例子吧
int a[20]<=>int[] a=new int[20] //意思是开辟int型的20个地址空间给a,a的类型是a[]。
typedef char sstring[MAX]<=>typedef char[MAX] sstring //这样,sstring就可以定义一唯字符型数组了。
如:sstring s1<=>char s1[MAX]。
这样,我们再理解刚才上面提到的问题:
typedef int a[10]<=>typedef int[10] a //也就是说a可以去定义一唯整形数组了。
typedef void (*p)(void) <=>typedef void(void) *p //可以用p去定义指向返回值为空值,参数也为空值的函数了。
typedef int Fun() <=> typedef int() Fun //意思是Fun可以去定义返回值为int型的函数了。
下面对typedef作较为详细准备的解释:
2)使用 typedef为现有类型创建同义字。 定义易于记忆的类型名
typedef原类型名 替换类型名;
如typedef int me;
me a;
typedef 还可以掩饰符合类型,如指针和数组。
char line[81];
定义一个 typedef,如下示:
typedef char Line[81];
Line text, secondline;
getline(text);
typedef struct tagNode
{
char *pItem;
pNode pNext;
} *pNode; //这样,pNode就相当于struct tagNode *;
pNode p;
同样,可以象下面这样隐藏指针语法:
typedef char * pstr;
int mystrcmp(pstr, pstr);
注意:标准函数 strcmp()有两个‘const char *'类型的参数。 ‘const pstr'被解释为‘char * const'(一个指向 char 的常量指针),而不是‘const char *'(指向常量 char 的指针)。
typedef const char * cpstr;
int mystrcmp(cpstr, cpstr); // 现在是正确的
记住:不管什么时候,只要为指针声明 typedef,那么都要在最终的 typedef 名称中加一个 const,以使得该指针本身是常量,而不是对象。
3)代码简化
上面讨论的 typedef 行为有点像 #define 宏,用其实际类型替代同义字。不同点是 typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。例如:
typedef int (*PF) (const char *, const char *);
这个声明引入了 PF 类型作为函数指针的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值。
再如一下面的三个例子(将复杂的式子用typedef简化):
对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头就行了。
(1)int *(*a[5])(int, char*); 如下转化表达:
typedef int *(*pFun)(int, char*); //pFun是我们建的一个类型别名
pFun a[5]; //使用定义的新类型来声明对象,等价于int* (*a[5])(int, char*);
(2)void (*b[10]) (void (*)());
typedef void (*pFunParam)(); //首先为上面表达式斜体加粗部分声明一个新类型
typedef void (*pFun)(pFunParam); //整体声明一个新类型
pFun b[10]; //使用定义的新类型来声明对象,等价于void (*b[10]) (void (*)());
(3)doube(*)() (*pa)[9]; //首先为上面表达式斜体加粗部分声明一个新类型
typedef double(*pFun)(); //整体声明一个新类型
typedef pFun (*pFunParam)[9]; //使用定义的新类型来声明对象,等价于doube(*)() (*pa)[9];
pFunParam pa;
4)促进跨平台开发
typedef 有另外一个重要的用途,那就是定义机器无关的类型,例如,你可以定义一个叫 REAL 的浮点类型,在目标机器上它可以自动获得最高的精度:
typedef long double REAL;
在不支持 long double 的机器上,该 typedef 看起来会是下面这样:
typedef double REAL;
并且,在连 double 都不支持的机器上,该 typedef 看起来会是这样:
typedef float REAL;
在大多数情况下,甚至这个微小的变动完全都可以通过奇妙的条件编译来自动实现。标准库广泛地使用 typedef 来创建这样的平台无关类型:
size_t,ptrdiff 和 fpos_t 就是其中的例子。此外,象 std::string 和 std::ofstream 这样的 typedef 还隐藏了长长的,难以理解的模板特化语法,例如:basic_string,allocator> 和 basic_ofstream>。
5)typedef 与#define的比较
(A)他们的不同:
我们以例子进行。
例一:
typedef char *pStr;
#define pStr char *;
通常讲,typedef要比#define要好,特别是在有指针的场合:
typedef char *pStr1;
#define pStr2 char *;
pStr1 s1, s2;
pStr2 s3, s4;
在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。
#define用法的一个例子:
#define f(x) x*x
main( )
{
int a=6,b=2,c;
c=f(a) / f(b);
printf("%d \\n",c);
}
以下程序的输出结果是: 36,出错。
在许多C语言编程规范中提到使用#define定义时,如果定义中包含表达式,必须使用括号:#define f(x) (x*x) ,这样才有正确结果。当然,使用typedef就没有这样的问题。
例二:
下面的代码中编译器会报一个错误,你知道是哪个语句错了吗?
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
是p2++出错了。上述代码中const pStr p2并不等于const char * p2,不是简单的替换。const pStr p2和const long x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为只读,因此p2++错误。
(B)#define与typedef引申谈
1) #define宏定义的特别长处:可使用 #ifdef ,#ifndef等来进行逻辑判断,使用#undef来取消定义。
2) typedef的特别长处:它符合范围规则,使用typedef定义的变量类型其作用范围限制在所定义的函数或者文件内(取决于此变量定义的位置),而宏定义则没有这种特性。
6)typedef与存储关键字
typedef 就像 auto,extern,mutable,static,和 register 一样,是一个存储类关键字。这并不是说 typedef 会真正影响对象的存储特性;它只是说在语句构成上,typedef 声明看起来象 static,extern 等类型的变量声明。第二个陷阱:
typedef register int FAST_COUNTER; // 错误
编译通不过。问题出在你不能在声明中有多个存储类关键字。因为符号 typedef 已经占据了存储类关键字的位置,在 typedef 声明中不能用 register(或任何其它存储类关键字)
接触了typedef多时,对它的了解是:用来声明一个别名,typedef后面的语法,是一个声明。
其实,他同define的差别是比较大的,不仅仅是替换问题。
如下
typedef int a[10]; typedef void (*p)(void)
typedef int Fun() ;
用上面的概念能解释了吗?是用a[10]来代替Int吗?答案是NO!
2、别人的解释:
typedef int Fun() ;
定义了一个函数类型Fun,所有这个类型的函数都返回一个int类型的值。
举个例子,假定有两个分别计算加和减的函数
int sum(int a, int b)
{
return (a + b);
}
int sub(int a, int b)
{
return (a - b);
}
typedef int CalcType(int a, int b); //这样CalcType就成了返回值为int型,接受参数为两个整
//数的函数。
int main()
{
int select = -1;
int result;
int a;
int b;
CalcType calculate[] = {sum, sub}; //留意。
printf("Please select calculation type\n");
scanf("%d\n", select);
printf("Input two value\n");
scanf("%d %d\n", &a, &b);
if (select == 0 || select == 1)
result = calculate[select](a, b);
return (0);
}
3、我的理解
1)举个例子吧
int a[20]<=>int[] a=new int[20] //意思是开辟int型的20个地址空间给a,a的类型是a[]。
typedef char sstring[MAX]<=>typedef char[MAX] sstring //这样,sstring就可以定义一唯字符型数组了。
如:sstring s1<=>char s1[MAX]。
这样,我们再理解刚才上面提到的问题:
typedef int a[10]<=>typedef int[10] a //也就是说a可以去定义一唯整形数组了。
typedef void (*p)(void) <=>typedef void(void) *p //可以用p去定义指向返回值为空值,参数也为空值的函数了。
typedef int Fun() <=> typedef int() Fun //意思是Fun可以去定义返回值为int型的函数了。
下面对typedef作较为详细准备的解释:
2)使用 typedef为现有类型创建同义字。 定义易于记忆的类型名
typedef原类型名 替换类型名;
如typedef int me;
me a;
typedef 还可以掩饰符合类型,如指针和数组。
char line[81];
定义一个 typedef,如下示:
typedef char Line[81];
Line text, secondline;
getline(text);
typedef struct tagNode
{
char *pItem;
pNode pNext;
} *pNode; //这样,pNode就相当于struct tagNode *;
pNode p;
同样,可以象下面这样隐藏指针语法:
typedef char * pstr;
int mystrcmp(pstr, pstr);
注意:标准函数 strcmp()有两个‘const char *'类型的参数。 ‘const pstr'被解释为‘char * const'(一个指向 char 的常量指针),而不是‘const char *'(指向常量 char 的指针)。
typedef const char * cpstr;
int mystrcmp(cpstr, cpstr); // 现在是正确的
记住:不管什么时候,只要为指针声明 typedef,那么都要在最终的 typedef 名称中加一个 const,以使得该指针本身是常量,而不是对象。
3)代码简化
上面讨论的 typedef 行为有点像 #define 宏,用其实际类型替代同义字。不同点是 typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。例如:
typedef int (*PF) (const char *, const char *);
这个声明引入了 PF 类型作为函数指针的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值。
再如一下面的三个例子(将复杂的式子用typedef简化):
对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头就行了。
(1)int *(*a[5])(int, char*); 如下转化表达:
typedef int *(*pFun)(int, char*); //pFun是我们建的一个类型别名
pFun a[5]; //使用定义的新类型来声明对象,等价于int* (*a[5])(int, char*);
(2)void (*b[10]) (void (*)());
typedef void (*pFunParam)(); //首先为上面表达式斜体加粗部分声明一个新类型
typedef void (*pFun)(pFunParam); //整体声明一个新类型
pFun b[10]; //使用定义的新类型来声明对象,等价于void (*b[10]) (void (*)());
(3)doube(*)() (*pa)[9]; //首先为上面表达式斜体加粗部分声明一个新类型
typedef double(*pFun)(); //整体声明一个新类型
typedef pFun (*pFunParam)[9]; //使用定义的新类型来声明对象,等价于doube(*)() (*pa)[9];
pFunParam pa;
4)促进跨平台开发
typedef 有另外一个重要的用途,那就是定义机器无关的类型,例如,你可以定义一个叫 REAL 的浮点类型,在目标机器上它可以自动获得最高的精度:
typedef long double REAL;
在不支持 long double 的机器上,该 typedef 看起来会是下面这样:
typedef double REAL;
并且,在连 double 都不支持的机器上,该 typedef 看起来会是这样:
typedef float REAL;
在大多数情况下,甚至这个微小的变动完全都可以通过奇妙的条件编译来自动实现。标准库广泛地使用 typedef 来创建这样的平台无关类型:
size_t,ptrdiff 和 fpos_t 就是其中的例子。此外,象 std::string 和 std::ofstream 这样的 typedef 还隐藏了长长的,难以理解的模板特化语法,例如:basic_string,allocator> 和 basic_ofstream>。
5)typedef 与#define的比较
(A)他们的不同:
我们以例子进行。
例一:
typedef char *pStr;
#define pStr char *;
通常讲,typedef要比#define要好,特别是在有指针的场合:
typedef char *pStr1;
#define pStr2 char *;
pStr1 s1, s2;
pStr2 s3, s4;
在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。
#define用法的一个例子:
#define f(x) x*x
main( )
{
int a=6,b=2,c;
c=f(a) / f(b);
printf("%d \\n",c);
}
以下程序的输出结果是: 36,出错。
在许多C语言编程规范中提到使用#define定义时,如果定义中包含表达式,必须使用括号:#define f(x) (x*x) ,这样才有正确结果。当然,使用typedef就没有这样的问题。
例二:
下面的代码中编译器会报一个错误,你知道是哪个语句错了吗?
typedef char * pStr;
char string[4] = "abc";
const char *p1 = string;
const pStr p2 = string;
p1++;
p2++;
是p2++出错了。上述代码中const pStr p2并不等于const char * p2,不是简单的替换。const pStr p2和const long x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为只读,因此p2++错误。
(B)#define与typedef引申谈
1) #define宏定义的特别长处:可使用 #ifdef ,#ifndef等来进行逻辑判断,使用#undef来取消定义。
2) typedef的特别长处:它符合范围规则,使用typedef定义的变量类型其作用范围限制在所定义的函数或者文件内(取决于此变量定义的位置),而宏定义则没有这种特性。
6)typedef与存储关键字
typedef 就像 auto,extern,mutable,static,和 register 一样,是一个存储类关键字。这并不是说 typedef 会真正影响对象的存储特性;它只是说在语句构成上,typedef 声明看起来象 static,extern 等类型的变量声明。第二个陷阱:
typedef register int FAST_COUNTER; // 错误
编译通不过。问题出在你不能在声明中有多个存储类关键字。因为符号 typedef 已经占据了存储类关键字的位置,在 typedef 声明中不能用 register(或任何其它存储类关键字)
- typedef用法总结
- typedef用法总结
- typedef用法总结!很棒!!!
- typedef用法总结
- typedef的用法总结
- typedef用法总结
- Typedef用法总结
- typedef用法总结
- typedef的用法总结
- Typedef 用法总结
- typedef用法总结
- typedef用法总结
- typedef用法总结
- typedef用法总结
- typedef的用法总结
- typedef用法总结
- 总结typedef用法
- Typedef用法总结
- highcharts图表内的tooltip提示框在IE浏览器下出现花屏的问题分析以及解决办法
- http://www.verysource.com/
- renderviewhost与webcontents关系
- LINUX移植——DM9000网卡移植
- python 实现MR
- typedef用法总结
- javascript实现动态增加行删除行.
- poj3617 Best Cow Line 贪心
- 推荐几个好的 Maven 常用仓库网址
- 2440开发板linux3.x.xx版移植
- php pdo连接数据库 解决中文乱码问题
- kvm与libvirt的编译与安装
- Android开发当中Parcelable接口的使用
- Android中广播的使用