C C++中typedef struct和struct的用法



《C C++中typedef struct和struct的用法》由会员分享,可在线阅读,更多相关《C C++中typedef struct和struct的用法(14页珍藏版)》请在装配图网上搜索。
1、1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 由于对typedef理解不够,因此从网上摘录了一些资料,整理如下: C/C++中 typedef struct 和 struct 的用法 struct _x1 { ...}x1;和 typede
2、f struct _x2{ ...} x2;有什么不同? 其实,前者是定义了类_X1和_x1的对象实例x1,后者是定义了类_x2和_x2的类别名x2 , 所以它们在使用过程中是有取别的.请看实例1. [知识点] 结构也是一种数据类型,可以使用结构变量,因此,象其它类型的变量一样,在使用结构变 量时要先对其定义。 定义结构变量的一般格式为: struct结构名 { 类型变量名; 类型变量名; }结构变量; 结构名是结构的标识符不是变量名。 另一种常用格式为: typedef struct 结构名 { 类型变量名; 44. 45. 46. 47. 48.
3、49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
类型变量名;
}结构别名;
另外注意:在C中,st rue t不能包含函数。在C++中,对st ruct进行了扩展,可以包含函数。
实例 1: struct, epp
#include
4、sing namespace std;
typedef struct _point{
int x;
int y;
}poin t; //定义类,给类一个别名
struct _hello{
int x,y;
} hello; //同时定义类和对象
int main()
{
point pt1;
pt1.x = 2;
pt 1.y = 5;
cout<< "ptpt1.x=" << pt1.x << "pt.y=" < 5、< pt2.x <<"pt2.y="< 6、.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
}
132.
133.
134.
135.
136. typedef struct 与 struct 的区别
137.
137. 1.基本解释
139.
138. typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数 7、据类型包括内部 数据类型(int,char等)和自定义的数据类型(struct等)。
141.
142.
143.
144. 在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是 简化一些比较复杂的类型声明。
145.
146.
147.
148.
至于typedef有什么微妙之处,请你接着看下面对几个问题的具体阐述。
149.
150.
151.
152.
2. typedef &结构的问题
153.
154.
155.
156.
当用下面的代码定义一个结构时,编译器报了一个错误,为什么呢?莫非C语言不允许在结构 8、中 包含指向它自己的指针吗?请你先猜想一下,然后看下文说明:
157.
158.
159.
160.
typedef struct tagNode
161.
162.
163.
164.
char *pItem;
165.
166.
pNode pNext;
168.
*pNode;
172.答案与分析:
174.
175.
176.
1、typedef的最简单使用
177.
178.
179.
180.
typedef long byte_4;
181.
182.
183.
184.
给已知数据类型lon 9、g起个新名字,叫byte_4。
185.
186.
187.
188.
2、typedef与结构结合使用
189.
190.
191.
192.
typedef struct tagMyStruct
193.
194.
195.
196.
int iNum;
197.
198.
long lLength;
199.
200.
MyStruet;
201.
202.
203.
204.
这语句实际上完成两个操作:
205.
206.
207.
208.
1)定义一个新的结构类型
209.
212.
struct tagMyStr 10、uct
216.
int iNum;
218.
long lLength;
219.
220.
};
221.
222.
223.
分析:tagMyStruct称为“tag”,即“标签”,实际上是一个临时名字,struct关键字和 tagMyStruct —起,构成了这个结构类型,不论是否有typedef,这个结构都存在。
225.
224.
226.
227.
228. 11、我们可以用struct tagMyStruct varName来定义变量,但要注意,使用
tagMyStruct varName来定义变量是不对的,因为struct和tagMyStruct合在一起才能表示一 个结构类型。
229.
230.
231.
232.
2) typedef为这个新的结构起了一个名字,叫MyStruet。
233.
234.
235.
236.
typedef struct tagMyStruct MyStruct;
237.
238.
239.
240.
来定义变量。
因此,MyStruct实际上相当于struct tagMyStru 12、et,我们可以使用MyStruct varName
241.
242.
243.
244.
答案与分析
245.
246.
247.
248.
C语言当然允许在结构中包含指向它自己的指针,我们可以在建立链表等数据结构的实现上 看到无数这样的例子,上述代码的根本问题在于typedef的应用。
249.
250.
251.
252. 根据我们上面的阐述可以知道:新结构建立的过程中遇到了 pNext域的声明,类型是 13、pNode, 要知道pNode表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字 也还不存在,也就是说这个时候编译器根本不认识pNode。
253.
255.
256.
解决这个问题的方法有多种:
257.
258.
259.
260.
261.
262.
typedef struct tagNode
263.
264.
265.
266.
char *pItem;
267.
268.
struct tagNode *pNext;
269.
270.
*pNode;
271.
272.
2)、
273.
274.
14、275.
276.
typedef struct tagNode *pNode;
277.
278.
struct tagNode
279.
280.
281.
282.
char *pItem;
283.
284.
pNode pNext;
285.
286.
};
287.
288.
289.
290.
注意:在这个例子中,你用typedef给一个还未完全声明的类型起新名字。C语言编译器支持这 种做法。
291.
292. 3)、规范做法:
293.
296. struct tagNode
297.
298. {
299.
29 15、9. char *pItem;
301.
300. struct tagNode *pNext;
303.
301. };
305.
302. typedef struct tagNode *pNode;
307.
308.
309.
310.
311.
303. C++中typedef关键字的用法
313.
304. Typedef声明有助于创建平台无关类型,甚至能隐藏复杂和难以理解的语法。不管怎样,使
用typedef能为代码带来意想不到的好处,通过本文你可以学习用typedef避免缺欠,从而使 代码更健壮。
315.
305. typedef声明,简称t 16、ypedef,为现有类型创建一个新的名字。比如人们常常使
用typedef来编写更美观和可读的代码。所谓美观,意指typedef能隐藏笨拙的语法构造以及 平台相关的数据类型,从而增强可移植性和以及未来的可维护性。本文下面将竭尽全力来揭 示typedef强大功能以及如何避免一些常见的陷阱。
317.
306. 如何创建平台无关的数据类型,隐藏笨拙且难以理解的语法?
319.
320.
321.
307. 使用typedefs为现有类型创建同义字。定义易于记忆的类型名
323.
308. typedef使用最多的地方是创建易于记忆的类型名,用它来归档程序员的意图。类型出现在 所声 17、明的变量名字中,位于’’typedef''关键字右边。例如:typedef int size;
325.
309. 此声明定义了一个int的同义字,名字为size。注意typedef并不创建新的类型。它仅 仅为现有类型添加一个同义字。你可以在任何需要int的上下文中使用size:
void measure(size * psz);
327.
310. size array[4];
329.
311. size len = file.getlength();
331.
312. std::vector 18、型,如指针和数组。例如,你不用象下面这样重复定义有81个 字符元素的数组:char line[81];
335.
314. char text[81];
337.
315. 定义一个typedef,每当要用到相同类型和大小的数组时,可以这样:
typedef char Line[81];
339.
316. Line text, secondline;
341.
317. getline(text);
343.
318. 同样,可以象下面这样隐藏指针语法:typedef char * pstr;
345.
319. int mystrcmp(pstr, pstr);
19、
347.
320. 这里将带我们到达第一个typedef陷阱。标准函数strcmp()有两个‘const char *'类型 的参数。因此,它可能会误导人们象下面这样声明mys trcmp():
int mystrcmp(const pstr, const pstr);
349.
321. 这是错误的,按照顺序,‘const pst r'被解释为‘char * cons t'(一个指向char的常量 指针),而不是‘const char *'(指向常量char的指针)。这个问题很容易解决:
typedef const char * cpstr;
351.
322. int my 20、strcmp(cpstr, cpstr); // 现在是正确的
353.
323. 记住:不管什么时候,只要为指针声明typedef,那么都要在最终的typedef名称中加一 个cons t,以使得该指针本身是常量,而不是对象。代码简化
355.
324. 上面讨论的typedef行为有点像#define宏,用其实际类型替代同义字。不同点 是typedef在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。例如: typedef int (*PF) (const char *, const char *);
357.
325. 这个声明引入了 PF类型作为函数指针的同义字 21、,该函数有两个const char *类型的参 数以及一个int类型的返回值。如果要使用下列形式的函数声明,那么上述这个typedef是不 可或缺的:PF Register(PF pf);
359.
326. Register()的参数是一个PF类型的回调函数,返回某个函数的地址,其署名与先前注册 的名字相同。做一次深呼吸。下面我展示一下如果不用typedef,我们是如何实现这个声明的: int (*Register (int (*pf)(const char *, const char *)))
361.
327. (const char *, const char *);
363 22、.
328. 很少有程序员理解它是什么意思,更不用说这种费解的代码所带来的出错风险了。显然,这 里使用typedef不是一种特权,而是一种必需。持怀疑态度的人可能会问:"0K,有人还会写这 样的代码吗?",快速浏览一下揭示signal()函数的头文件 23、象的存储特性;它只 是说在语句构成上,typedef声明看起来象static, extern等类型的变量声明。下面将带到第 二个陷阱:typedef register int FAST_COUNTER; // 错误
367.
330. 编译通不过。问题出在你不能在声明中有多个存储类关键字。因为符号typedef已经占据 了存储类关键字的位置,在typedef声明中不能用register (或任何其它存储类关键字)。促 进跨平台开发
369.
331. typedef有另外一个重要的用途,那就是定义机器无关的类型,例如,你可以定义一个 叫REAL的浮点类型,在目标机器上它可以i获得最高的 24、精度:typedef long double REAL;
371.
332. 在不支持long double的机器上,该typedef看起来会是下面这样:
typedef double REAL;
373.
333. 并且,在连double都不支持的机器上,该typedef看起来会是这样:、
typedef float REAL;
375.
334. 你不用对源代码做任何修改,便可以在每一种平台上编译这个使用REAL类型的应用程序。 唯一要改的是typedef本身。在大多数情况下,甚至这个微小的变动完全都可以通过奇妙的条件 编译来自动实现。不是吗?标准库广泛地使用typedef 25、来创建这样的平台无关类型:size_t, ptrdiff和fpos_t就是其中的例子。此外,象std::string和std::ofstream这样
的typedef还隐藏了长长的,难以理解的模板特化语法,例如:
basic_string 26、点? typedef char *pStr;
383.
336. #define pStr char *;
385.
337. 答案与分析:
387.
338. 通常讲,typedef要比#define要好,特别是在有指针的场合。请看例子:
typedef char *pStr1;
389.
339. #define pStr2 char *;
391.
340. pStrl s1, s2;
393.
341. pStr2 s3, s4;
395.
342. 在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了 char,不是我们
所预期 27、的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起 新名字。 #define 用法例子:#define f(x) x*x
397.
343. main()
399.
344. {
401.
345. int a=6, b=2, c;
403.
346. c=f(a) / f(b);
405.
347. printf("%d \\n", c);
407.
348. }
409.
349. 以下程序的输出结果是:36。
411.
350. 因为如此原因,在许多C语言编程规范中提到使用#define定义时,如果定义中包含表达式 28、,
必须使用括号,则上述定义应该如下定义才对:#define f(x) (x*x) 当然,如果你使用
typedef就没有这样的问题。
413.
351. 4. typedef & #define的另一例 下面的代码中编译器会报一个错误,你知道是哪个语
句错了吗?
415.
352. typedef char * pStr;
417.
353. char string[4] = "abc";
419.
354. const char *p1 = string;
421.
355. const pStr p2 = string;
423.
356. p1++;
4 29、25.
357. p2++;
427.
358. 答案与分析:
429.
359. 是p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的文本
替换。上述代码中 const pStr p2 并不等于 const char * p2°const pStr p2 和 const long x 本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而 不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为 只读,因此p2++错误。 #define与typedef引申谈
43 30、1.
360. 1) #define宏定义有一个特别的长处:可以使用#ifdef ,#ifndef等来进行逻辑判断, 还可以使用#undef来取消定义。
433.
361. 2) typedef也有一个特别的长处:它符合范围规则,使用typedef定义的变量类型其作用 范围限制在所定义的函数或者文件内(取决于此变量定义的位置),而宏定义则没有这种特性。
435.
362. 5. typedef &复杂的变量声明
437.
363. 在编程实践中,尤其是看别人代码的时候,常常会遇到比较复杂的变量声明,使用typedef 作简化自有其价值,比如:
439.
364. 下面是三个变 31、量的声明,我想使用typdef分别给它们定义一个别名,请问该如何做? >1: int *(*a[5])(int, char*);
441.
365. >2: void (*b[10]) (void (*)());
443.
366. >3. doube(*)() (*pa)[9];
445.
367. 答案与分析: 对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表
达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头就行了。>1:
int *(*a[5])(int, char*);
447.
368. //pFun是我们建的一个类型别名
4 32、49.
369. typedef int *(*pFun)(int, char*);
451.
370. //使用定义的新类型来声明对象,等价于int* (*a[5])(int, char*);
453.
371. pFun a[5];>2: void (*b[10]) (void (*)());
455.
372. 〃首先为上面表达式蓝色部分声明一个新类型
457.
373. typedef void (*pFunParam)();
459.
374. //整体声明一个新类型
461.
375. typedef void (*pFun)(pFunParam);
4 33、63.
376. //使用定义的新类型来声明对象,等价于void (*b[10]) (void (*)());
465.
377. pFun b[10];>3. doube(*)() (*pa)[9];
467.
378. 〃首先为上面表达式蓝色部分声明一个新类型
469.
379. typedef double(*pFun)();
471.
380. //整体声明一个新类型
473.
381. typedef pFun (*pFunParam)[9];
475.
382. //使用定义的新类型来声明对象,等价于doube(*)() (*pa)[9];
477.
383. pFunParam pa;
- 温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。