C/C++中结构体变量及指向结构体指针变量的内存分配问题
来源:互联网 发布:网络视频策划制作 编辑:程序博客网 时间:2024/05/03 22:31
一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。指针变量也可以用来指向结构体数组中的元素。
声明一个结构体变量,无论是否初始化,都开辟内存,声明一个结构体指针变量,对其初始化的时候才会开辟内存。
A a[3]; a是A型的,有3个,当然分配A乘3大小的空间
A* a; a是A*型的,当然只分配A*大小的空间,而不会分配A大小的空间结构体变量分配结构体本身大小的空间,结构体指针分配4个字节,其实任何类型的指针都是分配四个字节的指针空间。
所以:
A a[3]; //a里面是三个A变量,所以分配三个结构体大小
A *a; //a是一个指针,分配4个字节,就算A再大,a也只是4个字节,因为任何类型的指针都是4个字节。要使用a,必须先要对指针初始化,也即分配空间了。
如:
A *a;
a = (A*)malloc(sizeof(A));
我们完全可以撇开结构体,把问题简单化成int类型来说明这个指针问题:
int a1[10];
int *a2;
很容易知道,a1是包含10个int的数组,大小也就是10*sizeof(int)。我们可以直接使用a1不用再进行什么初始化或者分配空间,因为数组a1里面本身存放的就是int变量本身了。
然后a2,是一个int*的东西,也就是整型指针,a2不能存放int变量,它只能存放地址,一个int变量的地址。如果要使用a2,必须首先对a2初始化,即将它指向一个int变量的地址,如:
a2 = (int*)malloc(sizeof(int));
或者
int i = 10;
a2 = &i;
所以,malloc函数的作用是首先声明一个变量,然后返回该变量的地址。
所以:a2 = (int*)malloc(sizeof(int)) 的含义就是把该变量的地址赋值给a2,和a = &i 本质上并没有什么不同,只是一个变量是栈上,一个是堆上,都是一个地址赋值。
【例7.3】指向结构体变量的指针的应用。
- #include <iostream>
- #include <string>
- using namespace std;
- int main( )
- {
- struct Student//声明结构体类型student
- {
- int num;
- string name;
- char sex;
- float score;
- };
- Student stu;//定义Student类型的变量stu
- Student *p=&stu;//定义p为指向Student类型数据的指针变量并指向stu
- stu.num=10301;//对stu中的成员赋值
- stu.name="Wang Fun";//对string变量可以直接赋值
- stu.sex='f';
- stu.score=89.5;
- cout<<stu. num<<" "<<stu.name<<" "<<stu.sex<<" "<<
- stu.score<<endl;
- cout<<p -> num<<" "<<(*p).name<<" "<<(*p).sex<<" "<<(*p).score<<endl;
- return 0;
- }
10301 Wang Fun f 89.5 (通过结构体变量名引用成员)
10301 Wang Fun f 89.5 (通过指针引用结构体变量中的成员)
两个cout语句输出的结果是相同的。
为了使用方便和使之直观,C++提供了指向结构体变量的运算符->,例如p->num表示指针p当前指向的结构体变量中的成员num。
p->num 和(*p).num等价。
同样
p->name等价于(*p).name。
也就是说,以下3种形式等价:
- 结构体变量.成员名。如stu.num。
- (*p).成员名。如(*p).num。
- p->成员名。如p->num。
“->”称为指向运算符。
请分析以下几种运算:
- p->n 得到p指向的结构体变量中的成员n的值。
- p->n++ 得到p指向的结构体变量中的成员n的值,用完该值后使它加1。
- ++p->n 得到p指向的结构体变量中的成员n的值,并使之加1,然后再使用它。
用结构体变量和指向结构体变量的指针构成链表
链表是一种常见的重要的数据结构。图7.8表示最简单的一种链表(单向链表)的结构。图7.8
链表有一个“头指针”变量,图中以head表示,它存放一个地址。该地址指向一个元素。链表中的每一个元素称为“结点”,每个结点都应包括两个部分:
- 一是用户需要用的实际数据,
- 二是下一个结点的地址。
可以看到链表中各元素在内存中的存储单元可以是不连续的。要找某一元素,可以先找到上一个元素,根据它提供的下一元素地址找到下一个元素。
可以看到,这种链表的数据结构,必须利用结构体变量和指针才能实现。
可以声明一个结构体类型,包含两种成员,一种是用户需要用的实际数据,另一种是用来存放下一结点地址的指针变量。
例如,可以设计这样一个结构体类型:
- struct Student
- {
- int num;
- float score;
- Student *next; //next指向Student结构体变量
- };
图7.9
图中每一个结点都属于Student类型,在它的成员next中存放下一个结点的地址,程序设计者不必知道各结点的具体地址,只要保证能将下一个结点的地址放到前一结点的成员next中即可。
下面通过一个例子来说明如何建立和输出一个简单链表。
【例7.4】建立一个如图7.9所示的简单链表,它由3个学生数据的结点组成。输出各结点中的数据。
- #define NULL 0
- #include <iostream>
- using namespace std;
- struct Student
- {
- long num;
- float score;
- struct Student *next;
- };
- int main( )
- {
- Student a,b,c,*head,*p;
- a. num=31001;
- a.score=89.5; //对结点a的num和score成员赋值
- b. num=31003;
- b.score=90; //对结点b的num和score成员赋值
- c. num=31007;
- c.score=85; //对结点c的num和score成员赋值
- head=&a; //将结点a的起始地址赋给头指针head
- a.next=&b; //将结点b的起始地址赋给a结点的next成员
- b.next=&c; //将结点c的起始地址赋给b结点的next成员
- c.next=NULL; //结点的next成员不存放其他结点地址
- p=head; //使p指针指向a结点
- do
- {
- cout<<p->num<<" "<<p->score<<endl; //输出p指向的结点的数据
- p=p->next; //使p指向下一个结点
- } while (p!=NULL); //输出完c结点后p的值为NULL
- return 0;
- }
动态链表则是指各结点是可以随时插入和删除的,这些结点并没有变量名,只能先找到上一个结点,才能根据它提供的下一结点的地址找到下一个结点。只有提供第一个结点的地址,即头指针head,才能访问整个链表。如同一条铁链一样,一环扣一环,中间是不能断开的。
建立动态链表,要用到后面介绍的动态分配内存的运算符new和动态撤销内存的运算符delete。
用户栈是(运行时创建)是用户存放程序临时创建的局部变量,不包括静态变量,除此之外,在函数调用时,其参数也会被压入栈,并且带导函数调用结束后,函数的返回值也会存放到栈中。
堆是用于存放程序进程中被动态分配的内存段,它的大小不固定,可动态扩展,结束后必须free掉。
- C/C++中结构体变量及指向结构体指针变量的内存分配问题
- 【C++】指向结构体变量的指针
- C\C++中结构体变量与结构体指针内存分配问题
- C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题?
- C语言定义了一个结构体怎么分配内存?C\C++中结构体变量与结构体指针内存分配问题?
- c语言:通过指向结构体变量的指针变量输出结构体变量中成员的信息
- 【C语言经典实例】-指向结构体的指针变量
- 通过指向结构体变量的指针变量输出结构体变量中成员的信息
- 指向结构体变量的指针。
- 指向结构体变量的指针
- 指向结构体变量的指针
- 指向结构体变量的指针
- 指向结构体变量的指针
- C++指向结构体变量的指针
- C++指向结构体变量的指针
- C语言中结构体指针的成员变量访问
- C语言中->、变量、指针、结构体的解释,通俗易懂!
- C语言—指向函数的指针、全局变量和局部变量 、结构体、枚举
- office2016和Visio2016同时安装
- 编译原理:求非终结符的First集合
- c++数据结构—————静态链表防止内存泄漏
- kali 2.0加载msf数据库
- C++最小二乘法拟合-(线性拟合和多项式拟合)
- C/C++中结构体变量及指向结构体指针变量的内存分配问题
- Tarjan 缩点——HDU 5934
- python中with学习
- 图片文件Exif信息详细说明
- 面试总结
- jquery.modal.js
- 用.net core 写后端—— c++外的另一种选择?
- [leetcode]567. Permutation in String
- IT痴汉的工作现状50-神秘的键盘声