一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。指针变量也可以用来指向结构体数组中的元素。
声明一个结构体变量,无论是否初始化,都开辟内存,声明一个结构体指针变量,对其初始化的时候才会开辟内存。
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,然后再使用它。用户栈是(运行时创建)是用户存放程序临时创建的局部变量,不包括静态变量,除此之外,在函数调用时,其参数也会被压入栈,并且带导函数调用结束后,函数的返回值也会存放到栈中。
堆是用于存放程序进程中被动态分配的内存段,它的大小不固定,可动态扩展,结束后必须free掉。