结构体指针
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C++语言结构体和指针
指针也可以指向一个结构体,定义的形式一般为:
struct结构体名*变量名;
下面是一个定义结构体指针的实例:
上述代码已经测试。
注意:定义已经命名的结构体指针的时候必须用已命名结构体类型定义的结构体变量的地址进行初始化。
也可以在定义结构体的同时定义结构体指针:
上述代码已经测试
注意,结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必
pstu赋值只能写作:
struct stu *pstu = &stu1;
而不能写作:
struct stu *pstu = stu1;
还应该注意,结构体和结构体变量是两个不同的概念:结构体是一种数据类型,是一种创建变量的模板,编译器不会为它分配内存空间,就像int、float、char 这些关键字本身不占用内存一样;结构体变量才包含实实在在的数据,才需要内存来存储。下面的写法是错误的,不可能去取一个结构体名的地址,也不能将它赋值给其他变量:
struct stu *pstu = &stu;
struct stu *pstu = stu;
获取结构体成员
通过结构体指针可以获取结构体成员,一般形式为:
(*pointer).memberName
或者:
pointer->memberName
对了。
,有了它,可以通过结构体指针
直接取得结构体成员;这C语言中的唯一用途。
上面的两种写法是等效的,我们通常采用后面的写法,这样更加直观。
运行结果:
Name Num Age Group Score
Zhou ping 5 18 C 145.0
Zhang ping 4 19 A 130.5
Liu fang 1 18 A 148.5
Cheng ling 2 17 F 139.0
Wang ming 3 17 B 144.5
结构体指针作为函数参数
结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针。如果结构体成员较多,尤其是成员为数组时,传送的时间和空间开销会很大,影响程序的运行效率。所以最好的办法就是使用结构体指针,这时由实参传向形参的只是一个地址,非常快速。
要铭记的一点就是:数组名称始终代表数组的指针指向第一个元素,数组名称加一始终指向下一个数组元素。
c语言函数说明必须在主调函数之前,就是在开头先声明这个函数,告诉系统有这个函数,或者你要调用的函数放在前面。然后你再调用。
只能对结构体变量中的成员赋值,而不能对结构体类型赋值
对结构体变量中的成员(即“域”),可以单独使用,它的作用与地位相当于同类型的普通变量
结构体的成员也可以是一个结构体变量
===============================================================================
结构变量的三种定义方式
以上只是指定了一种结构体类型,它相当于一个模型,但其中并无具体数据,系统也不为之分配实际的内存单元为了能在程序中使用结构体类型的数据,应当定义结构体类型的变量,并在其中存放具体的数据。
定义结构体类型变量的方法可以采取以下3种方法定义结构体类型的变量。
1) 先声明结构体类型再定义变量名
如上面已定义了一个结构体类型Student,可以用它来定义结构体变量。如:
在C语言中,在定义结构体变量时,要在结构体类型名前面加上关键字Sttuct,C++ 保留了
C的用法,如:
struct Student studentl, student2;
提倡读者在编写C++程序时,使用C++新提出来的方法,即不必在定义结构体变量时加关键字Struct,这样使用更方便,而且与第8章中介绍的用类(class)名定义类对象的用法一致。
以上定义了student1和student2为结构体类型Student的变量,即它们具有Student类型的结构。如图7.2所示。
图7.2
在定义了结构体变量后,系统会为之分配内存单元。例如student1和student2在内存中各占63个字节(4+20+1+4+4+30=63)。
2) 在声明类型的同时定义变量。例如:
这种形式的定义的一般形式为:
struct结构体名
{
成员表列
}变量名表列;
3) 直接定义结构体类型变量。其一般形式为:
struct //注意没有结构体类型名
{
成员表列
}变量名表列;
这种方法虽然合法,但很少使用。
关于结构体类型,有几点要说明:
1) 不要误认为凡是结构体类型都有相同的结构。实际上,每一种结构体类型都有自己的结构,可以定义出许多种具体的结构体类型。
2) 类型与变量是不同的概念,不要混淆。只能对结构体变量中的成员赋值,而不能对结构体类型赋值。在编译时,是不会为类型分配空间的,只为变量分配空间。
3) 对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。
4) 成员也可以是一个结构体变量。
=============================================================================== 结构体的自引用(c++)
结构体作为一种类型,起成员可以是各种基本类型,当然也包括结构体这种类型。当一个结构体中想引用自身的结构时,是可以的,不过要注意用法。下面第一种是错误的,即我刚开始想象的那样子。第二种是正确的。
1.结构体定义中错误的自身引用:
struct A {
int a;
int b;
A c;
}pp;
为什么错误呢,这个大家应该可以想象,第三个成员c是个A类型,c的第三个成员也是个A类型,那么会一直有pp.c.c.c.c.c.c.c……,此结构体的大小没有结束,那么肯定是错误的,编译的时候肯定通不过。那么怎么能是引用自身呢,这就要看指针的功能了。
2.结构体定义中错误的自身引用:
struct A {
int a;
int b;
A *c;
}pp;
这样使用指针指向一个自身的结构体,那么第三个元素是个指针,占用一个地址空间的大小,那么pp的大小就是一个int,一个int,再一个指针的大小。c的具体内容需要在实际用的时候去赋值。这样就达到了自身引用的效果。而操作系统中使用的链表的实现也就是这样来的:
Structlist_head {
Structlist_head *next, *prev;
};
structdevice{
……
Structlist_head list;
……
}
假设在32位机器上,list_head的大小占用8字节,共存储两个指针,分别指向他的前一个节点和后一个节点。
指针变量占用内存的大小(字节数).在32位机上,所有指针类型变量占用内存字节数都为4因为32位机就是4字节* 8个二进制位/字节计算出来的.如果在64位机上,指针占用内存大小就是:8个字节.
===============================================================================