第六章 复合数据类型
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第六章复合数据类型
6.1变量和赋值的进一步讨论
一个变量是由四个要素组成的:一个名字、一个属性、一个关联和一个值。名字指命名变量的标识符;属性指变量可以存放那种类型的值;关联指存放变量的内存位置;值指该内存位置当前时刻存放的数据。
应该认识到这里的值是可能改变的,但任何时候在盒子里总有一个值(我们将无定义的随机值也当做一个特殊的值)。
根据变量在赋值运算中的使用方式,将变量的关联部分称为左值,变量的值部分称为右值。对于表达式而言,求值结果也存在是否可作为左值使用的问题。一般情况下,表达式的求值结果作为右值使用,但如果一个表达式的求职结果不是void类型,并且指派了一个变量,则该表达式可作为左值。
((i<0)?i:j)=1 .//合法的赋值运算
(i+j) =1 //不合法的赋值运算
6.2指针类型
变量以两种方式被使用:作为一个关联的名字和作为一个值的名字。
对变量的访问也有两种方式:直接访问和间接访问。
在C++中实现对变量的间接访问的方法是:先安排相关变量,专门用于存放变量地址。要间接访问时,先从这些变量获得待访问的变量的地址,然后再按所获得的地址去访问要访问的变量。
指针是存放其他变量地址的变量,所以从效果上看它们指向这些数据。指针使得数据不一定非得与某一特定变量名字相关联,指针可以指向一个没有名字的数据值。
6.2.1指针的声明
int age = 30; //声明一个存放年龄的整数类型变量
让C++编译程序知道有一个新的变量,该变量的名字是标识符age,编译程序会为它分配2个字节的存储空间(假如我们使用的机器上int用两个字节表示)并将30放在这些字节中,并且编译程序知道这些字节中存放的是整数类型数值而不是浮点类型或其他类型数据。
不直接访问age的存储空间地址,而是用age这个名字访问器其存储空间。
ptr常用作pointer的缩写
指针类型是在其他数据类型后加一个类型修饰符“*”,这个类型被称为指针的基类型。如int * age_ptr;
注意“*”仅用于修饰类型,而不是变量名字的一部分。
一个指针变量占用的存储空间大小取决于机器的内存寻址方式。
指针age_ptr的类型(int*)指明age_ptr仅能指向整数类型的值,而不能指向字符类型、浮点类型或其他类型的值,即age_ptr中存放的地址所指向的存储空间中只可存放整数类型的值。
将“*”与类型名写在一起表明int*是一种复合类型,但要注意
Int * p,q;
声明的却是一个整数类型的指针变量p和一个整数类型变量q
如果把“*”和指针变量写在一起,则可以连续声明几个指针变量。例如:
int *p,*q,*k;
注意(int *)并不能作为一个类型来使用,例如(int *) ptr;并不是一个声明,编译程序会将它理解为类型转换。
6.2.2指针的引用
“&”运算符放在操作数前面,操作数必须是一个变量名,表示取出操作数的存储空间地址;”*”运算符也放在操作数前面,操作数必须是一个指针变量,表示取出指针所指向存储空间中保持的值。在一个指针变量前面加上“*”有两种情况:一是声明一个指针变量,此时作为类型修饰符;二是访问指针变量所指向的变量的值,此时作为一元运算符。
空指针是值为0x00的指针变量,许多编译程序提供的函数库中定义了一个空指针名字NULL,其作用相当于0x00,赋值语句:
ptr=NULL;相当于ptr=0;
int *ptr;
声明指着ptr时没有初始化它,所以ptr中存放的值是不确定的,它随机地指向某一内存区域(这个区域的内容可能很关键)。如果为初始化ptr就使用它:
*ptr = 250;
那么存放250的两个字节将可能会写入内存中的关键区域。C++语言在编译与运行时都不报告这种错误,这种错误在程序开发后期才能被发现,并且这种错误的出现具有随机性,因而错误的定位与修改变得十分困难。
6.2.3指针的运算
指针变量的算术运算只能做加、减运算。必须注意指针的算术运算与指针的基类型是密切相关的。例如指针age_ptr的当前值为350606,经过如下运算:
age_ptr = age_ptr + 1;
age_ptr的当前值不是350607,而是350608。因为指针age_ptr的基类型是int,所以指针age_ptr 每次加1就指向下一个整数,所以他存放的地址值是加2而不是加1。
6.2.4按引用调用的参数传递方式
引用类型是在其他数据类型后加上一个类型修饰符“&”,该数据类型被称为引用的基类型,例如int&是基类型为int的引用类型。注意“&”在C++语言中既可作为类型修饰符,也可作为一元运算符(取操作数的地址)或二元运算符(两个操作数进行位与运算)
引用类型的变量并不真正创建一个新的对象,而是作为另一个对象的别名。
int i =1; //真正创建了一个整数类型的对象并初始化为1
int& ir = 1; //引用类型的变量必须初始化,指明ir是i的别名
引入ir作为i的别名后,对ir的运算就相当于作用在变量i上。
ir = 8; //相当于将8赋值给i
cout<<&ir; //相当于输出i的地址
C++语言引入引用类型的主要作用是提供按引用调用的参数传递方式。将函数的返回值类型定义为引用类型时,函数调用表达式可作为左值使用。
按值调用按引用调用
由于按引用调用不需要复制实际参数的一个副本,因而按引用调用的效率要高于按值调用,特别是当参数时比较大的复合数据类型时。有时候为了效率而使用按引用调用的参数传递方式,即使并不需要修改这些实际参数的值。为确保函数无副作用,可以使用保留字const修饰这个形式参数。
6.3数组类型
在数学上,常用一个向量表示一些相关数据组成的序列。在程序设计中,用数组来表示,数组是数据项的有序列表,这些数据项称为数组的元素。程序中数组有以下特点:
(1)数组中的每一个元素均属于同一类型,这种类型称为数组的基类型;
(2)每个数组中的元素个数一经确定后就保持不变,称为数组的长度;
(3)数组中的每一个元素均能直接访问,用数组下标来标识数组的元素;
(4)数组中的元素还允许是数组类型,从而产生二维数组、多维数组等结构。
6.3.1一维数组的声明
一维数组是相对多维数组而言,指数组中的元素不再是数组类型。一维数组只需要一个参数就可以确定数组内的一个数组元素。一维数组的声明方式为:
类型数组名[常量表达式];
常量表达式可出现常量或符号常量,但不允许有变量,因为C++语言不允许动态确定数组的长度,如:
int N;
cin>>N;
int scores[N]; //出错,因为N是变量
一个数组的所有元素在存储空间中是连续存放的,两个相邻的数组元素之间没有空隙。编译程序将根据数组的长度以及数组的基类型为数组分配相应大小的存储空间。编译程序为数组分配的存储空间地址是不确定。
数组的大小可以用sizeof()运算符取得,如果sizeof()的操作数是一个数组变量,它将返回整个数组占用的存储空间字节数。
6.3.2一维数组元素的引用与初始化
程序中使用数组时,通常引用的是数组中的一个个元素,而不是整个数组变量,如在屏幕上输出数组scores中的内容,不能用
Cout< 而必须将数组中的元素逐个地输出到屏幕。