typedefstruct用法详解和用法小结上课讲义_第1页
typedefstruct用法详解和用法小结上课讲义_第2页
typedefstruct用法详解和用法小结上课讲义_第3页
typedefstruct用法详解和用法小结上课讲义_第4页
免费预览已结束,剩余14页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、精品文档1. 基本解释typedef 为 C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。在编程中使用 typedef 目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。至于 typedef有什么微妙之处,请你接着看下面对几个问题的具体阐述。2. typedef &结构的问题当用下面的代码定义一个结构时, 编译器报了一个错误, 为什么呢?莫非 C语言不允许在结构中包含指向它自己的指针吗?请你先猜想一下,然后看下文说明:typedef struct ta

2、gNodechar *pItem;pNode pNext; *pNode;答案与分析:1、typedef 的最简单使用typedef long byte_4;给已知数据类型long 起个新名字,叫 byte_4 。2、 typedef与结构结合使用typedef struct tagMyStructint iNum;long lLength; MyStruct;这语句实际上完成两个操作:1) 定义一个新的结构类型struct tagMyStructint iNum;long lLength;精品文档精品文档分析:tagMyStruct 称为“ tag ”,即“标签”, 实际上是一个临时名字,

3、struct 关键字和 tagMyStruct 一起,构成了这个结构类型,不论是否有 typedef ,这个结构都存在。我们可以用 struct tagMyStruct varName 来定义变量,但要注意,使用 tagMyStruct varName 来定义变量是不对的,因为 struct 和 tagMyStruct 合在一起才能表示一个结构类型。2) typedef 为这个新的结构起了一个名字,叫 MyStruct 。typedef struct tagMyStruct MyStruct;因此, MyStruct 实际上相当于 struct tagMyStruct ,我们可以使用 MySt

4、ruct varName来定义变量。答案与分析C语言当然允许在结构中包含指向它自己的指针,我们可以在建立链表等数据结构的实现上看到无数这样的例子,上述代码的根本问题在于typedef的应用。根据我们上面的阐述可以知道: 新结构建立的过程中遇到了 pNext 域的声明,类型是 pNode,要知道 pNode表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字也还不存在, 也就是说这个时候编译器根本不认识 pNode。解决这个问题的方法有多种:1) 、typedef struct tagNodechar *pItem;struct tagNode *pNext; *pNode

5、; 2) 、typedef struct tagNode *pNode;struct tagNodechar *pItem;pNode pNext;注意:在这个例子中,你用 typedef 给一个还未完全声明的类型起新名字。 C 语言编译器支持这种做法。精品文档精品文档3) 、规范做法:typedef uint32 (* ADM_READDATA_PFUNC)( uint16*, uint32 );这个以前没有看到过 , 个人认为是宇定义一个 uint32 的指针函数 ,uint16*, uint32 为函数里的两个参数 ; 应该相当于 #define uint32 (* ADM_READDA

6、TA_PFUNC)( uint16*, uint32 );struct在代码中常见两种形式:struct A/.;struct/. A;这其实是两个完全不同的用法:前者叫做“结构体类型定义”,意思是:定义 中的结构为一个名称是“ A”的结构体。这种用法在 typedef 中一般是:typedef struct tagA /故意给一个不同的名字,作为结构体的实名/. A; / 结构体的别名。后者是结构体变量定义,意思是:以 中的结构,定义一个名称为"A" 的变量。这里的结构体称为匿名结构体,是无法被直接引用的。也可以通过 typedef为匿名结构体创建一个别名,从而使得它可以

7、被引用:typedef struct/. A; / 定义匿名结构体的别名为 A第二篇:在 C和 C+中 struct和 typedef struct的区别在 C 和 C+有三种定义结构的方法。typedef struct int data;int text;精品文档精品文档 S1;/ 这种方法可以在 c 或者 c+中定义一个 S1 结构struct S2 int data;int text;/ 这种定义方式只能在 C+中使用,而如果用在 C中,那么编译器会报错struct int data;int text; S3;这种方法并没有定义一个结构,而是定义了一个 s3 的结构变量,编译器会为 s3

8、 内存。void main()S1 mine1;/ OK ,S1是一个类型S2 mine2;/ OK,S2是一个类型S3 mine3;/ OK,S3不是一个类型S1.data = 5;/ ERRORS1是一个类型S2.data = 5;/ ERRORS2是一个类型S3.data = 5;/ OKS3是一个变量另外,对与在结构中定义结构本身的变量也有几种写法struct S6 精品文档精品文档S6* ptr;/ 这种写法只能在 C+中使用typedef struct S7* ptr; S7;/ 这是一种在 C 和 C+中都是错误的定义如果在 C 中,我们可以使用这样一个“曲线救国的方法“type

9、def struct tagS8tagS8 * ptr; S8;第三篇: struct和 typedef struct分三块来讲述:1 首先:在 C 中定义一个结构体类型要用typedef:typedef struct Studentint a;Stu;于是在声明变量的时候就可:Stu stu1;如果没有 typedef就必须用 struct Student stu1;来声明这里的 Stu 实际上就是 struct Student的别名。另外这里也可以不写Student (于是也不能 struct Student stu1;了)typedef structint a;Stu;但在 c+里很简单

10、,直接struct Studentint a;精品文档精品文档于是就定义了结构体类型Student ,声明变量时直接Student stu2;=2 其次:在 c+中如果用 typedef 的话,又会造成区别: struct Studentint a;stu1;/stu1是一个变量typedef struct Student2int a;stu2;/stu2是一个结构体类型使用时可以直接访问stu1.a但是 stu2 则必须先 stu2 s2;然后 s2.a=10;=3 掌握上面两条就可以了,不过最后我们探讨个没多大关系的问题如果在 c 程序中我们写:typedef structint num;

11、 int age; aaa,bbb,ccc;这算什么呢?我个人观察编译器( VC6)的理解,这相当于 typedef structint num; int age; aaa ; typedef aaa bbb; typedef aaa ccc;也就是说 aaa,bbb,ccc 三者都是结构体类型。声明变量时用任何一个都可以 , 在c+中也是如此。但是你要注意的是这个在 c+中如果写掉了 typedef 关键字,那么 aaa, bbb, ccc 将是截然不同的三个对象。第四篇: C/C+中 typedef struct和 struct的用法struct _x1 .x1;和 typedef str

12、uct _x2 . x2;有什么不同?其实 , 前者是定义了类 _x1 和_x1 的对象实例 x1, 后者是定义了类 _x2 和 _x2 的类别名 x2 ,所以它们在使用过程中是有取别的. 请看实例 1.精品文档精品文档知识点结构也是一种数据类型 , 可以使用结构变量 , 因此 , 象其它 类型的变量一样 , 在使用结构变量时要先对其定义。定义结构变量的一般格式为:struct结构名类型 变量名 ;类型 变量名 ;. 结构变量 ;结构名是结构的标识符不是变量名。另一种常用格式为 :typedef struct结构名类型 变量名 ;类型 变量名 ;. 结构别名 ;另外注意 : 在 C 中, st

13、ruct 不能包含函数。在 C+中,对 struct 进行了扩展,可以包含函数。= =实例 1: struct.cpp#include <iostream>using namespace std;精品文档精品文档typedef struct _pointint x;int y;point; /定义类,给类一个别名struct _helloint x,y; hello; /同时定义类和对象int main()point pt1;pt1.x = 2;pt1.y = 5;cout<< "ptpt1.x=" << pt1.x << &

14、quot;pt.y=" <<pt1.y <<endl;/hello pt2;/pt2.x = 8;/pt2.y =10;/cout<<"pt2pt2.x="<< pt2.x <<"pt2.y="<<pt2.y <<endl;/ 上面的 hello pt2; 这一行编译将不能通过 . 为什么 ?/ 因为 hello 是被定义了的对象实例了 ./ 正确做法如下 :用 hello.x和 hello.yhello.x = 8;hello.y = 10;cout<&

15、lt; "hellohello.x=" << hello.x << "hello.y=" <<hello.y <<endl;return 0;精品文档精品文档第五篇:问答Q: 用 struct 和 typedef struct 定义一个结构体有什么区别?为什么会有两种方式呢?struct Studentint a; stu;typedef struct Student2int a;stu2;A:事实上,这个东西是从 C语言中遗留过来的, typedef 可以定义新的复合类型或给现有类型起一个别名,在 C 语

16、言中,如果你使用struct xxx;的方法,使用时就必须用struct xxx var来声明变量,而使用typedef struct 的方法 就可以写为 xxx var;不过在 C+中已经没有这回事了, 无论你用哪一种写法都可以使用第二种方式声明变量,这个应该算是 C 语言的糟粕。用法小结第一、四个用途用途一:定义一种类型的别名, 而不只是简单的宏替换。 可以用作同时声明指针型的多个对象。比如:char* pa, pb; / 这多数不符合我们的意图,它只声明了一个指向字符变量的指针,/ 和一个字符变量;以下则可行:typedef char* PCHAR; /一般用大写PCHAR pa, pb

17、; / 可行,同时声明了两个指向字符变量的指针虽然:char *pa, *pb;精品文档精品文档也可行,但相对来说没有用 typedef 的形式直观,尤其在需要大量指针的地方, typedef 的方式更省事。用途二:用在旧的 C 的代码中(具体多旧没有查),帮助 struct 。以前的代码中,声明 struct 新对象时,必须要带上 struct ,即形式为: struct 结构名 对象名,如:struct tagPOINT1int x;int y;struct tagPOINT1 p1;而在 C+中,则可以直接写:结构名对象名,即:tagPOINT1 p1;估计某人觉得经常多写一个struc

18、t太麻烦了,于是就发明了:typedef struct tagPOINTint x;int y;POINT;POINT p1; / 这样就比原来的方式少写了一个 struct ,比较省事,尤其在大量使用的时候或许,在 C+中, typedef 的这种用途二不是很大,但是理解了它,对掌握以前的旧代码还是有帮助的, 毕竟我们在项目中有可能会遇到较早些年代遗留下来的代码。用途三:用 typedef来定义与平台无关的类型。比如定义一个叫 REAL 的浮点类型,在目标平台一上, 让它表示最高精度的类型为:typedef long double REAL;在不支持 long double的平台二上,改为:

19、typedef double REAL;在连 double都不支持的平台三上,改为:typedef float REAL;也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。标准库就广泛使用了这个技巧,比如size_t 。精品文档精品文档另外,因为 typedef 是定义了一种类型的新别名, 不是简单的字符串替换, 所以它比宏来得稳健(虽然用宏有时也可以完成以上的用途)。用途四:为复杂的声明定义一个新的简单的别名。 方法是:在原来的声明里逐步用别名替换一部分复杂声明, 如此循环,把带变量名的部分留到最后替换, 得到的就是原声明的最简化版。举例:1.原声明: in

20、t *(*a5)(int, char*);变量名为 a,直接用一个新别名pFun 替换 a 就可以了:typedef int *(*pFun)(int, char*);原声明的最简化版:pFun a5;2.原声明: void (*b10) (void (*)();变量名为 b,先替换右边部分括号里的,pFunParam为别名一:typedef void (*pFunParam)();再替换左边的变量b,pFunx 为别名二:typedef void (*pFunx)(pFunParam);原声明的最简化版:pFunx b10;3.原声明: doube(*)() (*e)9;变量名为 e,先替换

21、左边部分, pFuny 为别名一:typedef double(*pFuny)();再替换右边的变量e,pFunParamy为别名二typedef pFuny (*pFunParamy)9;原声明的最简化版:pFunParamy e;理解复杂声明可用的“右左法则”:从变量名看起,先往右,再往左,碰到一个圆括号就调转阅读的方向;括号内分析完就跳出括号,还是按先右后左的顺序,如此循环,直到整个声明分析完。举例:int (*func)(int *p);首先找到变量名func ,外面有一对圆括号,而且左边是一个* 号,这说明 func是一个指针;然后跳出这个圆括号,先看右边,又遇到圆括号,这说明 (*

22、func) 是一个函数,所以 func 是一个指向这类函数的指针,即函数指针,这类函数具有 int* 类型的形参,返回值类型是 int 。int (*func5)(int *);func 右边是一个 运算符,说明 func 是具有 5 个元素的数组; func 的左边有一个 * ,说明 func 的元素是指针(注意这里的 * 不是修饰 func ,而是修饰 func5 的,原因是 运算符优先级比 * 高,func 先跟 结合) 。跳出这个括号, 看右边,精品文档精品文档又遇到圆括号,说明 func 数组的元素是函数类型的指针, 它指向的函数具有 int* 类型的形参,返回值类型为 int 。也

23、可以记住 2 个模式:type (*)(.)函数指针type (*)数组指针第二、两大陷阱陷阱一:记住, typedef 是定义了一种类型的新别名,不同于宏,它不是简单的字符串替换。比如:先定义:typedef char* PSTR;然后:int mystrcmp(const PSTR, const PSTR);const PSTR 实际上相当于 const char*吗?不是的,它实际上相当于char*const 。原因在于 const 给予了整个指针本身以常量性,也就是形成了常量指针char*const 。简单来说,记住当 const 和 typedef 一起出现时, typedef 不会

24、是简单的字符串替换就行。陷阱二:typedef 在语法上是一个 存储 类的关键字(如 auto 、extern 、mutable 、static 、 register 等一样),虽然它并不真正影响对象的 存储 特性,如:typedef static int INT2; /不可行编译将失败,会提示“指定了一个以上的存储类”。以上资料出自:作者:赤龙第三、 typedef与 #define的区别案例一:通常讲, typedef 要比 #define要好,特别是在有指针的场合。请看例子:typedef char *pStr1;#define pStr2 char *;pStr1 s1, s2;精品文

25、档精品文档pStr2 s3, s4;在上述的变量定义中, s1、s2、 s3 都被定义为 char * ,而 s4 则定义成了 char ,不是我们所预期的指针变量, 根本原因就在于 #define 只是简单的字符串替换而 typedef 则是为一个类型起新名字。案例二:下面的代码中编译器会报一个错误,你知道是哪个语句错了吗?typedef char * pStr;char string4 = "abc"const char *p1 = string;const pStr p2 = string;p1+;p2+;是 p2+出错了。这个问题再一次提醒我们: typedef 和

26、 #define 不同,它不是简单的文本替换。上述代码中 const pStr p2 并不等于 const char * p2。const pStr p2 和 const long x 本质上没有区别,都是对变量进行只读限制,只不过此处变量 p2 的数据类型是我们自己定义的而不是系统固有类型而已。 因此,const pStr p2 的含义是:限定数据类型为 char * 的变量 p2 为只读,因此 p2+错误。第四部分资料:使用typedef抑制劣质代码摘要: Typedef 声明有助于创建平台无关类型,甚至能隐藏复杂和难以理解的语法。不管怎样,使用 typedef 能为代码带来意想不到的好处

27、,通过本文你可以学习用 typedef 避免缺欠,从而使代码更健壮。typedef 声明,简称 typedef ,为现有类型创建一个新的名字。 比如人们常常使用 typedef 来编写更美观和可读的代码。 所谓美观,意指 typedef 能隐藏笨拙的语法构造以及平台相关的数据类型,从而增强可移植性和以及未来的可维护性。本文下面将竭尽全力来揭示 typedef 强大功能以及如何避免一些常见的陷阱。Q:如何创建平台无关的数据类型,隐藏笨拙且难以理解的语法?A: 使用 typedefs为现有类型创建同义字。精品文档精品文档定义易于记忆的类型名typedef使用最多的地方是创建易于记忆的类型名,用它来

28、归档程序员的意图。类型出现在所声明的变量名字中,位于''typedef''关键字右边。例如:typedef int size;此声明定义了一个int的同义字,名字为size 。注意typedef 并不创建新的类型。 它仅仅为现有类型添加一个同义字。 你可以在任何需要 int 的上下文中使用 size :void measure(size * psz); size array4;size len =file.getlength();std:vector <size> vs; typedef 还可以掩饰符合类型,如指针和数组。例如,你不用象下面这样重复定

29、义有 81 个字符元素的数组:char line81;chartext81; 定义一个 typedef,每当要用到相同类型和大小的数组时,可以这样:typedef char Line81; Line text, secondline;getline(text);同样,可以象下面这样隐藏指针语法:typedef char * pstr;int mystrcmp(pstr, pstr);这里将带我们到达第一个typedef 陷阱。标准函数 strcmp()有两个 const char * 类型的参数。因此,它可能会误导人们象下面这样声明mystrcmp() :int mystrcmp(const

30、pstr, const pstr);这是错误的,按照顺序, constpstr 被解释为 char * const (一个指向 char的常量指针),而不是 constchar * (指向常量 char 的指针)。这个问题很容易解决:typedef const char * cpstr; int mystrcmp(cpstr, cpstr); /现在是正确的记住: 不管什么时候,只要为指针声明 typedef,那么都要在最终的 typedef名称中加一个 const,以使得该指针本身是常量,而不是对象。代码简化上面讨论的 typedef 行为有点像 #define 宏,用其实际类型替代同义字。

31、不同点是 typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。例如:typedef int (*PF) (const char *, const char *);这个声明引入了PF 类型作为函数指针的同义字,该函数有两个constchar * 类型的参数以及一个int类型的返回值。如果要使用下列形式的函数声明,那么上述这个typedef是不可或缺的:PF Register(PF pf);Register() 的参数是一个 PF 类型的回调函数,返回某个函数的地址, 其署名与先前注册的名字相同。 做一次深呼吸。 下面我展示一下如果不用 typedef ,我们是如何实现这个声明的:精品文档精品文档int (*Register (int (*pf)(const char *, const char *) (const char *,const char *); 很少有程序员理解它是什么意思,更不用说这种

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论