c++结构类型小谈
c++结构类型小谈
发布时间: 6:03:08
编辑:www.fx114.net
本篇文章主要介绍了"c++结构类型小谈",主要涉及到c++结构类型小谈方面的内容,对于c++结构类型小谈感兴趣的同学可以参考一下。
[知识点] &
一 。结构类型
结构也是一种数据类型,&可以使用结构变量,&因此,&&象其它&类型的变量一样,&在使用结构变量时要先对其定义。 &&
&&&&定义结构变量的一般格式为: &&
&&&&&struct&结构名 &&
&&&&&&&&&&类型&&变量名; &&
&&&&&&&&&&类型&&变量名; &&
&&&&&&&&&&... &&
&&&&&}&结构变量; &&
&&&&结构名是结构的标识符不是变量名。 &&
另一种常用格式为:&& &&
&typedef&struct&结构名 &&
&&&&&&&&&&类型&&变量名; &&
&&&&&&&&&&类型&&变量名; &&
&&&&&&&&&&... &&
&&&&&}&结构别名; &&
另外注意:&&在C中,struct不能包含函数。在C++中,对struct进行了扩展,可以包含函数。 &
====================================================================== &&
实例1:&&struct.cpp &&
using&namespace& &&
typedef&struct&_point{ &&
&&&&&&&&&&int&x; &&
&&&&&&&&&&int&y; &&
&&&&&&&&&&}&//定义类,给类一个别名& &&
&&&&&&&&&&&&&&&&& &&
struct&_hello{ &&
&&&&&&&int&x,y;&&&&&&& &&
&&&&&&}&&//同时定义类和对象 &&
&&&&&&& &&
&&&&&&&&& &&
int&main() &&
{&&&&&&&&&& &&
&&&&point&pt1;&&&&&& &&
&&&& pt1.x &=& 2 ; &&
&&&& pt1.y &=& 5 ; &&
&" pt pt1.x ="&
&"pt .y ="&
&//hello&pt2;& &&
&&&&// pt2.x &=& 8 ; &&
&&&&// pt2.y &= 10 ; &&
&&&&//cout
" pt2 pt2.x ="
"pt2 .y ="
&&&&//上面的hello&pt2;这一行编译将不能通过.&为什么? &&
&&&&//因为hello是被定义了的对象实例了. &&
&&&&//正确做法如下:&用hello.x和hello.y &&
&&&& hello.x &=& 8 ; &&
&&&& hello.y &=& 10 ;&& &&
&" hello hello.x ="&
&"hello .y ="&
&&&&return&0;&&&&&&&&&&&&& &&
typedef&struct与struct的区别 &&
1.&基本解释 &&
typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。 &&
在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。 &&
至于typedef有什么微妙之处,请你接着看下面对几个问题的具体阐述。 &&
2.&typedef&&&结构的问题 &&
当用下面的代码定义一个结构时,编译器报了一个错误,为什么呢?莫非C语言不允许在结构中包含指向它自己的指针吗?请你先猜想一下,然后看下文说明: &&
typedef&struct&tagNode &&
char&*pI &&
pNode&pN &&
***与分析: &&
1、typedef的最简单使用 &&
typedef&long&byte_4; &&
给已知数据类型long起个新名字,叫byte_4。 &&
2、&typedef与结构结合使用 &&
typedef&struct&tagMyStruct &&
int&iN &&
long&lL &&
这语句实际上完成两个操作: &&
1)&定义一个新的结构类型 &&
struct&tagMyStruct &&
int&iN &&
long&lL &&
分析:tagMyStruct称为&tag&,即&标签&,实际上是一个临时名字,struct&关键字和tagMyStruct一起,构成了这个结构类型,不论是否有typedef,这个结构都存在。 &&
我们可以用struct&tagMyStruct&varName来定义变量,但要注意,使用tagMyStruct&varName来定义变量是不对的,因为struct&和tagMyStruct合在一起才能表示一个结构类型。 &&
2)&typedef为这个新的结构起了一个名字,叫MyStruct。 &&
typedef&struct&tagMyStruct&MyS &&
因此,MyStruct实际上相当于struct&tagMyStruct,我们可以使用MyStruct&varName来定义变量。 &&
***与分析 &&
C语言当然允许在结构中包含指向它自己的指针,我们可以在建立链表等数据结构的实现上看到无数这样的例子,上述代码的根本问题在于typedef的应用。 &&
根据我们上面的阐述可以知道:新结构建立的过程中遇到了pNext域的声明,类型是pNode,要知道pNode表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字也还不存在,也就是说这个时候编译器根本不认识pNode。 &&
解决这个问题的方法有多种: &&
typedef&struct&tagNode &&
char&*pI &&
struct&tagNode&*pN &&
typedef&struct&tagNode&*pN &&
struct&tagNode &&
char&*pI &&
pNode&pN &&
注意:在这个例子中,你用typedef给一个还未完全声明的类型起新名字。C语言编译器支持这种做法。 &&
3)、规范做法: &&
struct&tagNode &&
char&*pI &&
struct&tagNode&*pN &&
typedef&struct&tagNode&*pN &&
C++中typedef关键字的用法 &&
Typedef&声明有助于创建平台无关类型,甚至能隐藏复杂和难以理解的语法。不管怎样,使用&typedef&能为代码带来意想不到的好处,通过本文你可以学习用&typedef&避免缺欠,从而使代码更健壮。 &&
&&&&&&typedef&声明,简称&typedef,为现有类型创建一个新的名字。比如人们常常使用&typedef&来编写更美观和可读的代码。所谓美观,意指&typedef&能隐藏笨拙的语法构造以及平台相关的数据类型,从而增强可移植性和以及未来的可维护性。本文下面将竭尽全力来揭示&typedef&强大功能以及如何避免一些常见的陷阱。 &&
&&&&&&如何创建平台无关的数据类型,隐藏笨拙且难以理解的语法? &&
使用&typedefs&为现有类型创建同义字。定义易于记忆的类型名 &&
typedef&使用最多的地方是创建易于记忆的类型名,用它来归档程序员的意图。类型出现在所声明的变量名字中,位于&''typedef''&关键字右边。例如:typedef&int& &&
此声明定义了一个&int&的同义字,名字为&size。注意&typedef&并不创建新的类型。它仅仅为现有类型添加一个同义字。你可以在任何需要&int&的上下文中使用&size:void&measure(size&*&psz); &&
size&array[4]; &&
size& len &=& file .getlength(); &&
std::vector&
typedef&还可以掩饰符合类型,如指针和数组。例如,你不用象下面这样重复定义有&81&个字符元素的数组:char&line[81]; &&
char&text[81]; &&
定义一个&typedef,每当要用到相同类型和大小的数组时,可以这样:typedef&char&Line[81]; &&
Line&text,& &&
getline(text); &&
同样,可以象下面这样隐藏指针语法:typedef&char&*& &&
int&mystrcmp(pstr,&pstr); &&
这里将带我们到达第一个&typedef&陷阱。标准函数&strcmp()有两个&const&char&*'类型的参数。因此,它可能会误导人们象下面这样声明&mystrcmp():int&mystrcmp(const&pstr,&const&pstr); &&
这是错误的,按照顺序,&const&pstr'被解释为&char&*&const'(一个指向&char&的常量指针),而不是 &const&char&*'(指向常量&char&的指针)。这个问题很容易解决:typedef&const&char&*& &&
int&mystrcmp(cpstr,&cpstr);&//&现在是正确的 &&
记住:不管什么时候,只要为指针声明&typedef,那么都要在最终的&typedef&名称中加一个&const,以使得该指针本身是常量,而不是对象。代码简化 &&
上面讨论的&typedef&行为有点像define&宏,用其实际类型替代同义字。不同点是&typedef&在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。例如:typedef&int&(*PF)&(const&char&*,&const&char&*); &&
这个声明引入了&PF&类型作为函数指针的同义字,该函数有两个&const&char&*&类型的参数以及一个&int&类型的返回值。如果要使用下列形式的函数声明,那么上述这个&typedef&是不可或缺的:PF&Register(PF&pf); &&
Register()&的参数是一个&PF&类型的回调函数,返回某个函数的地址,其署名与先前注册的名字相同。做一次深呼吸。下面我展示一下如果不用&typedef,我们是如何实现这个声明的:int&(*Register&(int&(*pf) (const&char&*,&const&char&*))) &&
(const&char&*,&const&char&*); &&
很少有程序员理解它是什么意思,更不用说这种费解的代码所带来的出错风险了。显然,这里使用&typedef&不是一种特权,而是一种必需。持怀疑态度的人可能会问:"OK,有人还会写这样的代码吗?",快速浏览一下揭示&signal()函数的头文件&
,一个有同样接口的函数。typedef&和存储类关键字(storage&class&specifier) &&
这种说法是不是有点令人惊讶,typedef&就像&auto,extern,mutable,static,和®ister&一样,是一个存储类关键字。这并是说&typedef&会真正影响对象的存储特性;它只是说在语句构成上,typedef&声明看起来象&static,extern&等类型的变量声明。下面将带到第二个陷阱:typedef®ister&int&FAST_COUNTER;&//&错误 &&
编译通不过。问题出在你不能在声明中有多个存储类关键字。因为符号&typedef&已经占据了存储类关键字的位置,在&typedef&声明中不能用®ister(或任何其它存储类关键字)。促进跨平台开发 &&
typedef&有另外一个重要的用途,那就是定义机器无关的类型,例如,你可以定义一个叫&REAL&的浮点类型,在目标机器上它可以i获得最高的精度:typedef&long&doubleℜ &&
在不支持&long&double&的机器上,该&typedef&看起来会是下面这样:typedef&doubleℜ &&
并且,在连&double&都不支持的机器上,该&typedef&看起来会是这样:、typedef&floatℜ &&
你不用对源代码做任何修改,便可以在每一种平台上编译这个使用&REAL&类型的应用程序。唯一要改的是&typedef&本身。在大多数情况下,甚至这个微小的变动完全都可以通过奇妙的条件编译来自动实现。不是吗?&标准库广泛地使用&typedef&来创建这样的平台无关类型:size_t,ptrdiff&和&fpos_t&就是其中的例子。此外,象&std::string&和&std::ofstream&这样的&typedef&还隐藏了长长的,难以理解的模板特化语法,例如:basic_string
,&char_traits
,allocator
&和&basic_ofstream
,&char_traits
typedef&&define的问题 有下面两种定义pStr数据类型的方法,两者有什么不同?哪一种更好一点?typedef&char&*pS &&
#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就没有这样的问题。 &&
4.&typedef&&define的另一例 下面的代码中编译器会报一个错误,你知道是哪个语句错了吗? &&
typedef&char&*&pS &&
char&string[4]&=&"abc"; &&
const&char&* p1 &=& string ; &&
const&pStr& p2 &=& string ; &&
***与分析: &&
是p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的文本替换。上述代码中const&pStr&p2并不等于const&char&*&p2。const&pStr&p2和const&long&x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2 的数据类型是我们自己定义的而不是系统固有类型而已。因此,const&pStr&p2的含义是:限定数据类型为char&*的变量p2为只读,因此 p2++错误。 #define与typedef引申谈 &&
1)define宏定义有一个特别的长处:可以使用ifdef&,#ifndef等来进行逻辑判断,还可以使用#undef来取消定义。 &&
2)&typedef也有一个特别的长处:它符合范围规则,使用typedef定义的变量类型其作用范围限制在所定义的函数或者文件内(取决于此变量定义的位置),而宏定义则没有这种特性。 &&
5.&typedef&&&复杂的变量声明 &&
在编程实践中,尤其是看别人代码的时候,常常会遇到比较复杂的变量声明,使用typedef作简化自有其价值,比如: &&
下面是三个变量的声明,我想使用typdef分别给它们定义一个别名,请问该如何做?
1:int&*(*a[5])(int,&char*); &&
2:void&(*b[10])&(void&(*)()); &&
3.&doube(*)()&(*pa)[9]; &&
***与分析: 对复杂变量建立一个类型别名的方法很简单,你只要在传统的变量声明表达式里用类型名替代变量名,然后把关键字typedef加在该语句的开头就行了。
1:int&*(*a[5])(int,&char*); &&
//pFun是我们建的一个类型别名 &&
typedef&int&*(*pFun)(int,&char*); &&
//使用定义的新类型来声明对象,等价于int*&(*a[5])(int,&char*); &&
pFun&a[5];
2:void&(*b[10])&(void&(*)()); &&
//首先为上面表达式蓝色部分声明一个新类型 &&
typedef&void&(*pFunParam)(); &&
//整体声明一个新类型 &&
typedef&void&(*pFun)(pFunParam); &&
//使用定义的新类型来声明对象,等价于void&(*b[10])&(void&(*)()); &&
pFun&b[10];
3.&doube(*)()&(*pa)[9]; &&
//首先为上面表达式蓝色部分声明一个新类型 &&
typedef&double(*pFun)(); &&
//整体声明一个新类型 &&
typedef&pFun&(*pFunParam)[9]; &&
//使用定义的新类型来声明对象,等价于doube(*)()&(*pa)[9]; &&
pFunParam& &
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接: