实验4 构造数据类型概览.docx
《实验4 构造数据类型概览.docx》由会员分享,可在线阅读,更多相关《实验4 构造数据类型概览.docx(21页珍藏版)》请在冰豆网上搜索。
![实验4 构造数据类型概览.docx](https://file1.bdocx.com/fileroot1/2022-11/16/589b1302-3278-4064-acc6-946204527f17/589b1302-3278-4064-acc6-946204527f171.gif)
实验4构造数据类型概览
实验4构造数据类型
一、实验目的
1.掌握指针的定义和使用。
2.掌握指针在函数参数传递中的作用。
3.掌握引用的作用、定义及使用。
4.掌握结构体类型变量、结构体类型指针及结构体数组的定义和使用。
5.熟悉联合体的概念与应用,了解联合型、枚举型的定义与使用。
6.使用构造类型数据解决实际应用问题,优化程序设计。
二、知识要点
(一)指针
1.指针和指针变量
所谓指针就是变量、数组、函数等的存储地址。
指针变量就是用于存放指针的变量。
直接按变量地址存取变量值的方式为直接访问方式。
将变量地址存放在另一个变量(即指针变量)中,再通过指针变量来存取变量值的方式为间接访问方式。
指针变量可以存储各类标识符的地址,包括变量、数组、函数、对象,甚至是指针。
同类型的对象取地址的方式却不尽相同:
(1)一般变量的地址,用取地址符“&”加变量名;
(2)数组的地址用数组名表示;
(3)函数的地址用函数名表示。
2.指针变量的定义
C++规定指针变量必须先定义后引用,定义一个指针变量的一般形式为:
<类型名>*<指针变量名>;
3.两个重要的运算符
(1)“&”为取地址运算符
其作用是取出变量的内存地址。
若变量i的起始地址为2000,则&i的运算结果为2000。
注意:
指针变量中只能存放地址(指针),不能存放其他非地址类型的数据。
(2)“*”为指针运算符
其作用是返回指针变量所指向的变量的值。
4.指针变量的运算
(1)算术运算
指针变量的算术运算主要有指针变量的自加、自减、加n和减n操作。
这些算术运算的规则是:
<指针变量>=<指针变量>+/-sizeof(<指针变量类型>)*n
其中,n表示元素的个数,自加、自减操作相当于n=1。
(2)指针变量的关系运算
指针变量的关系运算是对指针变量值的大小比较,如大于(>)、小于(<)、等于(==)和不等于(!
=),它们都能对两个指针变量存储的地址进行比较,如果两个相同类型的指针变量相等,则说明这两个指针变量指向同一个地址。
*******************************************************************************
说明:
本部分在chapter9中讲述
(3)new运算符
用new可以动态的分配内存空间,并将分配内存的地址赋给指针变量,使用new为指针变量动态分配内存空间的语句有3种格式:
格式一:
<指针变量>=new<类型>;
该语句的作用是分配由类型确定大小的一片连续内存空间,并将内存空间的首地址赋给指针变量。
格式二:
<指针变量>=new<类型>(初值);
该语句的作用是除完成分配空间的功能外,还将初值存入所分配的内存空间中。
格式三:
<指针变量>=new<类型>[<常量表达式>];
该语句的作用是分配指定类型的数组空间,并将数组的首地址赋给指针变量。
(4)delete运算符
运算符delete用来将动态分配的内存空间归还给系统,有两种格式:
格式一:
delete<指针变量>;
该语句的作用是将指针变量所指的内存空间归还给系统。
格式二:
delete[]<指针变量>;
该语句的作用是将指针变量所指的一维数组内存空间归还给系统。
*******************************************************************************
5.指针变量作为函数参数
在C++中,有3种类型的指针可以作为函数的参数,它们是:
(1)一般对象(变量)的指针作为函数的参数;
(2)数组的指针(字符串的指针)作为函数的参数;
(3)函数的指针作为函数的参数。
第一种情况是地址参数。
第二种情况是指针作为参数非常多的一种情况,它体现出指针作为参数的优势就是简单、灵活、高效。
第三种情况较复杂,主要是为了设计出一个更通用的函数。
6.指向数组元素的指针
(1)指向一维数组元素的指针
定义一个指向数组元素的指针变量与定义一个指向变量的指针变量相同,但要注意指针变量类型必须与其指向的数组类型相同。
一般格式为:
<数组类型名>*<指针变量名>;
(2)指向二维数组元素的指针
定义指向二维数组元素的指针与定义指向一维数组元素的指针相同。
一般格式为:
<数组类型名>*<指针变量名>;
需要说明的是,在二维数组中有行地址的概念。
C++规定,二维数组a中第i行的地址用a+i或&a[i]表示,并且行地址的值与行首地址的值是相同的,即:
a+i=&a[i]=a[i]=&a[i][0]
但要注意它们的类型不同,前两个是行地址,后两个是数组元素地址。
行地址a+i与&a[i]只能用于指向一维数组的指针变量,而不能用于普通指针变量,例如:
inta[2][3];
int*p=a+0;//错误!
类型不同,应该为int*p=&a[0][0];
(3)指向一维数组的指针
二维数组名可以认为是指向一维数组的常指针,与该指针对应的指针变量定义一般格式为:
<数组类型名>(*<指针变量名>)[第2维数组长度]
第i行第j列元素a[i][j]的地址有下面4种表示方法:
a[i]+j、*(a+i)+j、&a[i][0]+j、&a[i][j]
或
p[i]+j、*(p+i)+j、&p[i][0]+j、&p[i][j]
7.通过指针引用数组元素
(1)通过指向数组元素的指针引用一维数组元素
通过指针引用一维数组元素,一般有以下两种方法:
下标法:
<数组名/指针变量名>[下标]
指针法:
*(数组名/指针变量名+下标)
在C++中,下标法实际上是指针法的一种缩写形式,在编译器编译程序时,首先需要将下标法转化成指针法,也就是说,从编译角度看,指针法引用数组元素要更快一些。
假设指针变量P指向一维数组a,则根据数组元素存储的连续性以及指针的运算规则,可以得出以下结论:
①p+1表示指向数组中的下一个元素;
②若p=&a[0],i是一个整数,那么
●p+i或a+i就是a[i]的地址(i不能超过数组的最大长度);
●*(p+i)或*(a+i)代表数据元素a[i];
●a[i]也可以写成p[i],两者是等价的;
(2)通过指向一维数组的指针引用二维数组元素
指向一维数组的指针基本等同于二维数组名,它们的区别是前者是变量,后者是常量。
C++规定,引用数组a的第i行第j列元素a[i][j]的值有下面的4种表示方法:
*(a[i]+j)、*(*(a+i)+j)、*(&a[i][0]+j)、a[i][j]
或
*(p[i]+j)、*(*(p+i)+j)、*(&p[i][0]+j)、p[i][j]
8.数组名作函数参数
数组名可以用作函数的实参和形参。
数组名代表数组首地址,因此当用数组名作实参调用函数时是把数组的首地址传递给形参,而不是把数组的值传递给形参,即形参接受的是实参传递过来的首地址,这样就使得实参数组与形参数组共同占用同一段内存。
在实际编程中,若想在函数中改变数组元素的值,实参与形参一般有如下几种对应情况:
(1)形参和实参都用数组名,例如:
main()
{inta[10];
…
f(a,10);
…
}
f(intx[],intn)
{
…
}
(2)实参用数组,形参用指针变量,例如:
main()
{inta[10];
…
f(a,10);
…
}
f(int*x,intn)
{
…
}
(3)实参、形参都用指针变量,例如:
main()
{inta[10],*p;
p=a;
…
f(p,10);
…
}
f(int*x,intn)
{
…
}
(4)实参为指针变量,形参为数组名,例如:
main()
{inta[10],*p;
p=a;
…
f(p,10);
…
}
f(intx[],intn)
{
…
}
9.字符串的表示形式(建议应用C++的string类)
在C++程序中,字符数组和字符型指针都可以实现对字符串的存储和运算。
用数组的形式表示一个字符串,例如:
charstring[]=“IloveBeijing”;
还可以用字符指针指向一个字符串,例如:
char*str=“IloveBeijing”;
其中str是一个字符指针变量,而“IloveBeijing”是一个字符串常量,str指向它的首地址。
字符数组与字符指针的区别是:
(1)字符数组由若干个元素组成,每个元素中存放一个字符,而字符指针变量中存放的是地址(字符串的首地址),而不是将字符串放到字符指针变量中。
(2)字符数组在编译的同时即已分配存储单元,有确定的地址,而字符指针在运行时才会存在。
10.字符串指针作函数参数
在函数之间传递一个字符串,可以使用地址传递的方法,即用字符数组作参数或用指向字符串的指针变量作参数。
在被调用的函数中可以改变字符串的内容,主调函数中可以得到改变了的字符串。
11.函数指针变量调用函数
经过编译后,每个函数都被分配给一个入口地址,这个入口地址就称为函数的指针,因此可以通过一个指针变量指向这个入口地址,从而达到通过指针变量调用函数的目的。
指向函数的指针变量的一般定义形式为:
<类型名>(*<指针变量名>)([形参表]);
12.指向函数的指针作函数参数
函数指针变量的作用通常是把指针作为函数传递给其他函数,通过这种方式传递函数的地址,从而实现了一个函数作为另一个函数的参数,目的是设计出更通用、更强大的函数。
13.指针数组的概念
指针数组也是数组,不同的是其数组元素不是一般的数据类型,而是指针,即内存单元的地址。
指针数组中的每一个元素都相当于一个指针变量,而且这些指针必须指向同一种类型的变量。
指针数组的声明方式和普通数组的声明方式类似。
声明一维指针数组的一般形式为:
<数据类型>*数组名[数组长度];
其中,数据类型确定指针数组中每个元素(指针变量)的类型,数组名是指针数组的名称,同时也是这个数组的首地址,数组长度用来确定数组元素的个数。
声明二维指针数组的一般方式为:
<数据类型><*数组名>[第1维数组长度][第2维数组长度];
14.指向指针的指针
指针可以指向任何类型,包括指针类型。
指针也是变量,当然也有地址,那么就可以用另外一个指针来存放某一指针的地址,这个存放某一指针地址的指针就是“指向指针的指针”。
定义指向指针的指针变量的一般形式为:
<数据类型>**<指针变量名>;
对于指向指针的指针来说,我们可以用“*”运算符得到其存储的内容,因为其内容仍然是一个地址,所以可再次应用“*”运算符,取得该地址存储的内容。
(二)引用
引用是某个变量或对象的别名,它的值和地址都与被引用的变量或对象的值和地址相同,对引用的所有操作实际上都是应用在被引用的变量或对象身上的。
当引用的变量变化的时候,原变量的值也会发生变化。
定义引用的一般形式为:
类型标识符&引用名=目标变量名;
引用的目的主要是作为函数的形参,在函数参数传递中解决大对象的传递效率和空间不如意的问题。
用引用传递函数的参数能保证参数传递中不产生副本,提高传递的效率,且通过const的使用,保证了引用传递的安全性。
引用与指针的区别在于:
指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作,程序中使用指针使程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。
(三)结构体、共用体和枚举
1.概念理解
数组是一组有序数据的集合,数组中的每一个元素都属于同一个数据类型。
用一个统一的数组