链表 指向结构体变量的指针 数据结构 线性表基础(基于c++)

指向结构体变量的指针

       一个结构体变量的指针该变量所占据内存的起始位置。可以设置一个指针变量来指向一个结构体变量,此时指针变量的值就是该结构体变量的起始位置。

       指针也可以用来指向结构体数组中的元素。

     A 通过指向结构体变量的指针引用结构体成员

       例子1:
       结构体变量的指针变量的应用

#include <iostream>
#include <string>
using namespace std;
int main()
{
	struct student
	{
		int num;
		string name;
		char sex;
		float score;
	};
	student s;
	student *p=&s;
	s.num=91022333;
	s.sex='f';
	s.name="lihaozhe";
	s.score=92.13;
	cout<<s.num<<' '<<s.name<<' '<<s.sex<<' '<<s.score<<endl;
	cout<<(*p).num<<' '<<(*p).name<<' '<<(*p).sex<<' '<<(*p).score<<endl;
	return 0;
}

       注:(*p)表示指针变量p指向的结构体变量。(*p).num是p指向的结构体变量中的成员num。等价于s.num

              (*p).num中的括号不可省略,因为‘.’优先于'*'

       为了更加方便直观,c++提供了指向结构体变量的成员运算符“->”。(指向运算符)形象地表示了“指向关系”。例如:p->num就表示指针p指向结构体的成员num。

       一下三种表达等价:
       1. 结构体变量.成员名;

       2. (*p).变量名;

       3. p->变量名;

     B 用结构体变量和指向结构体变量的指针构成链表

       链表是一种常见且重要的数据结构。

       链表有一个“头指针”的变量,他存放一个地址,该地址指向链表第一个元素。

       链表中的每一个元素称为“结点”,每一个结点都应包括两部分:1. 用户需要用的实际数据;2. 下一个节点的地址。

       头指针->第一个元素->第二个元素->...->最后一个元素。

       最后一个元素不再指向其他元素,称为表尾。它的地址部分放一个“NULL”(表示空地址),链表到此结束。

       正因为它的这种特性,链表中各元素在内存中的存储单元可以是不连续的。要找某一元素,可以先找到上一个元素,根据他提供的下一个元素地址找到下一个元素。

       这种链表的数据结构,必须要用结构体和指针才能实现。可以先声明一个结构体类型,包括两种成员:1. 用户所需要的实际数据;2. 用来存放下一节点地址的指针变量。

struct student
{
	int num;
	float score;
	student *next;
}

       在使用链表时,程序设计者不必知道具体各节点的具体地址,只要能保证将下一节点的地址放到前一节点的成员next中即可。

       例子1:

       如何建立和输出一个简单的链表。(由三个学生数据的结点组成,输出各节点中的数据)

#include <iostream>
#include <string>
using namespace std;
struct student
{
	int num;
	float score;
	student *next;
};
int main()
{
	student a,b,c,*head,*p;
	a.num=222;a.score=77.7;
	b.num=233;b.score=77.77;
	c.num=666;c.score=92.13;
	head=&a;
	a.next=&b;
	b.next=&c;
	c.next=NULL;
	p=head;
	do
	{
		cout<<p->num<<' '<<p->score<<endl;
		p=p->next; 
	}while(p!=NULL);
	return 0;
}

       注:1. 各个结点是如何构成链表的?开始时使head指向a结点,a.next指向b结点,b.next指向c结点,这就构成了链表关系。                     c.next=NULL的作用是使c.next不指向任何有用的存储单元

               2. 指针变量p有什么作用?在输出链表时要借助指针变量p。“p=p->next;”是为输出下一个节点做准备。此时指针变量p的值已经          是下一个节点的地址(占据内存的起始位置)。

               3. 本例子是比较简单的静态链表。所有节点都是在程序中定义的,不是临时开辟的,也不能用完后释放。对各个节点的访问既          可以通过上一结点的next指针访问,也可以通过结构体变量名a,b,c访问。

               4. 动态链表:各节点可以随时插入和删除的,这些结点并没有变量名。只能先找到上一个结点才能根据他提供的下一结点的地址       找到下一结点。只有提供第一个结点的地址——头指针head,才能访问整个链表。(需要用到动态分配内存的运算符“new”和动态撤销       内存的运算符“delate”)

     C 用new和delete运算符进行动态分配和撤销存储空间

       在软件开发中常常需要动态的分配和撤销内存空间(例如,动态链表中结点的插入与删除)。作为运算符的new和delete,相比函数有更高的执行效率。

new int;//开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(指针)
new int(100);//开辟存放一个整数的空间,并制定该整书的数值为100,返回一个指向该存储空间的地址(指针)
new char[10];//开辟一个存放字符数组(包括10个元素)的空间,返回字符数组首元素的地址
new int[5][4];//开辟一个存放二位整形数组(大小为5*4)的空间,返回首元素的地址
float *p=new float(3.14159);//开辟一个存放单精度数的空间,并指定该数的初始值为3.14159,将返回的该空间的地址赋给指针变量p 

        注:new运算符使用的一般格式为:new 类型 (初值)

               用new分配数组空间时,不能指定初值。

               如果由于内存不足等原因而无法正常分配空间时,则new会返回一个空指针NULL,用户可以根据该指针的值判断分配空间是否           成功。

       delete运算符的使用格式:

       delete 指针变量              (对变量)

       delete[]指针变量              (对数组)

       例子1:

       临时开辟一个存储空间一存放一个结构体数据。

#include <iostream>
#include <string>
using namespace std;
struct student
{
	string name;
	int num;
	char sex;
};
int main()
{
	student *p;
	p=new student;
	p->name="li hao zhe";
	p->num=666;
	p->sex='m';
	cout<<p->name<<' '<<p->num<<' '<<p->sex<<endl;
	delete p;
	return 0;
}

       注:在main函数中并没有定义结构体变量,而是定义了一个基类型为student的指针变量p,并由new开辟一段空间以存放一个student类型的数据,空间的大小由系统根据student自动弹出,不必用户指定。

               执行new得到i个指向student类型数据的指针(即所开辟的存储空间的起始地址),把他赋给p。就可以通过p来对这个无名的结构体变量进行操作。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值