目录
4.1 数组
4.2 字符串
4.3 string 类简介
4.3.4 string 类 I/O
4.4结构简介
4.5 共用体
4.6 枚举
4.7 指针和自由存储空间
4.8 指针、数组和指针算术
4.8.1 程序说明
4.8.2指针小结
4.8.5 自动存储、静态存储和动态存储
4.9 类型组合
4.10 数组的替代品
4.11 总结
练习题
C++是在 C 语言基础上开发的一种集面向对象编程、泛型编程和过程化编程于一体的编程语言,是C语言的超集。本书是根据2003年的ISO/ANSI C++标准编写的,通过大量短小精悍的程序详细而全面地阐述了 C++的基本概念和技术,并专辟一章介绍了C++11新增的功能。
《C++ Primer Plus(第6版)中文版》分18章,分别介绍了C++程序的运行方式、基本数据类型、复合数据类型、循环和关系表达式、分支语句和逻辑运算符、函数重载和函数模板、内存模型和名称空间、类的设计和使用、多态、虚函数、动态内存分配、继承、代码重用、友元、异常处理技术、string类和标准模板库、输入/输出、C++11新增功能等内容。
《C++ Primer Plus(第6版)中文版》针对C++初学者,从C语言基础知识开始介绍,然后在此基础上详细阐述C++新增的特性,因此不要求读者有C语言方面的背景知识。《C++ Primer Plus(第6版)中文版》可作为高等院校教授C++课程的教材,也可供初学者自学C++时使用。
本章内容包括:创建和使用数组。创建和使用 C-风格字符串。创建和使用 string 类字符串。使用方法 getline( )和 get( )读取字符串。混合输入字符串和数字。创建和使用结构。创建和使用共用体。创建和使用枚举。创建和使用指针。使用 new 和 delete 管理动态内存。创建动态数组。创建动态结构。自动存储、静态存储和动态存储。vector 和 array 类简介。
4.1 数组
- 存储在每个元素中的值的类型;
- 数组名;
- 数组中的元素数。
数组的初始化规则:
4.2 字符串
4.3 string 类简介
4.3.4 string 类 I/O
4.4结构简介
C++中的结构的可以满足要求(存储篮球运动员的信息)。结构是一种比数组更灵活的数据格式,因为同一个结构可以存储多种类型的数据,这使得能够将有关篮球运动员的信息放在一个结构中,从而将数据的表示合并到一起。如果要跟踪整个球队,则可以使用结构数组。结构也是C++OOP堡垒(类)的基石。学习有关结构的知识将使我们离C++的核心OOP更近。
4.5 共用体
4.6 枚举
4.7 指针和自由存储空间
对于指针,需要指出的另一点是,new分配的内存块通常与常规变量声明分配的内存块不同。变量nights和pd的值都存储在被称为栈(stack)的内存区域中,而new从被称为堆(heap)或自由存储区(free store)的内存区域分配内存。第9章将更详细地讨论这一点。
4.8 指针、数组和指针算术
指针和数组基本等价的原因在于指针算术(pointer arithmetic)和C++内部处理数组的方式。首先,我们来看一看算术。将整数变量加1后,其值将增加1;但将指针变量加1后,增加的量等于它指向的类型的字节数。将指向double的指针加1后,如果系统对double使用8个字节存储,则数值将增加8;将指向shot的指针加1后,如果系统对short使用2个字节存储,则指针值将增加2。程序清单4.19演示了这种令人吃惊的现象,它还说明了另一点:C++将数组名解释为地址。
4.8.1 程序说明
注意: 1 后,其增加的值等于指向的类型占用的字节数
4.8.2指针小结
刚才已经介绍了大量指针的知识,下面对指针和数组做一总结。
1.声明指针
要声明指向特定类型的指针,请使用下面的格式:
typeName pointerName;
下面是一些示例:
double pn;
/pn can point to a double value
char pci
/pc can point to a char value
其中,pn和pc都是指针,而double*和char*是指向double的指针和指向char的指针。
2.给指针赋值
应将内存地址赋给指针。可以对变量名应用&运算符,来获得被命名的内存的地址,ew运算符返回
未命名的内存的地址。
下面是一些示例:
double pn;
/pn can point to a double value
double pa;
//so can pa
char pci
/pc can point to a char value
double bubble 3.2;
pn &bubble;
/assign address of bubble to pn
pc new char;
/assign address of newly allocated char memory to pc
pa new double[30]i//assign address of 1st element of array of 30 double to pa
3.对指针解除引用
对指针解除引用意味着获得指针指向的值。对指针应用解除引用或间接值运算符(*)来解除引用。因
此,如果像上面的例子中那样,pn是指向bubble的指针,则*pn是指向的值,即3.2。
下面是一些示例:
cout <*pn;/print the value of bubble
*pc ='S';/place 's'into the memory location whose address is pc
另一种对指针解除引用的方法是使用数组表示法,例如,pO]与*pn是一样的。决不要对未被初始化
为适当地址的指针解除引用。
4.区分指针和指针所指向的值
如果pt是指向int的指针,则*pt不是指向nt的指针,而是完全等同于一个int类型的变量。pt才是指针。
下面是一些示例:
int pt new int;
/assigns an address to the pointer pt
*pt =5;
/stores the value 5 at that address
5.数组名
在多数情况下,C++将数组名视为数组的第一个元素的地址。
下面是一个示例:
int tacos [10];
/now tacos is the same as &tacos [0]
一种例外情况是,将szof运算符用于数组名用时,此时将返回整个数组的长度(单位为字节).
6.指针算术
C++允许将指针和整数相加。加1的结果等于原来的地址值加上指向的对象占用的总字节数。还可以
将一个指针减去另一个指针,获得两个指针的差。后一种运算将得到一个整数,仅当两个指针指向同一个
数组(也可以指向超出结尾的一个位置)时,这种运算才有意义:这将得到两个元素的间隔。
下面是一些示例:
int tacos[10]={5,2,8,4,1,2,2,4,6,8}:
int pt tacos;
/suppose pf and tacos are the address 3000
ptpt 1;
/now pt is 3004 if a int is 4 bytes
int*pe=&tacos【9】;
/pe is 3036 if an int is 4 bytes
pepe 1;
/now pe is 3032,the address of tacos [8]
int diff pe -pt;
/diff is 7,the separation between
/tacos [8]and tacos [1]
7.数组的动态联编和静态联编
使用数组声明来创建数组时,将采用静态联编,即数组的长度在编译时设置:
int tacos[10];//static binding,size fixed at compile time
使用w]运算符创建数组时,将采用动态联编(动态数组),即将在运行时为数组分配空间,其长度
也将在运行时设置。使用完这种数组后,应使用delete[]释放其占用的内存:
int size;
cin >size;
int pz new int [size];/dynamic binding,size set at run time
▣。
delete [pz;
/free memory when finished
8.数组表示法和指针表示法
使用方括号数组表示法等同于对指针解除引用:
第4章复合类型
111
tacos [o]means *tacos means the value at address tacos
tacos [3]means *(tacos 3)means the value at address tacos 3
数组名和指针变量都是如此,因此对于指针和数组名,既可以使用指针表示法,也可以使用数组
表示法。
下面是一些示例:
int pt new int [10];
/pt points to block of 10 ints
*pt=5;
/set element number 0 to 5
pt[0]=6:
/reset element number 0 to 6
pt[9】=44;
/set tenth element (element number 9)to 44
int coats [10]
*(c0ats+4)=12;
/set coats(4]to 12
4.8.5 自动存储、静态存储和动态存储
根据用于分配内存的方法,C++有 3 种管理数据内存的方式:自动存储、静态存储和动态存储(有时 也叫作自由存储空间或堆)。在存在时间的长短方面,以这 3 种方式分配的数据对象各不相同。下面简要地介绍每种类型(C++11 新增了第四种类型—线程存储,这将在第 9 章简要地讨论)。1.自动存储在函数内部定义的常规变量使用自动存储空间,被称为自动变量(automatic variable),这意味着它们在所属的函数被调用时自动产生,在该函数结束时消亡。例如,程序清单 4.22 中的 temp 数组仅当 getname( ) 函数活动时存在。当程序控制权回到 main( )时,temp 使用的内存将自动被释放。如果 getname( )返回 temp 的地址,则 main( )中的 name 指针指向的内存将很快得到重新使用。这就是在 getname( )中使用 new 的原因之一。 实际上,自动变量是一个局部变量,其作用域为包含它的代码块。代码块是被包含在花括号中的一段代码。到目前为止,我们使用的所有代码块都是整个函数。然而,在下一章将会看到,函数内也可以有代码块。如果在其中的某个代码块定义了一个变量,则该变量仅在程序执行该代码块中的代码时存在。 自动变量通常存储在栈中。这意味着执行代码块时,其中的变量将依次加入到栈中,而在离开代码块时,将按相反的顺序释放这些变量,这被称为后进先出(LIFO)。因此,在程序执行过程中,栈将不断地增大和缩小。2.静态存储静态存储是整个程序执行期间都存在的存储方式。使变量成为静态的方式有两种:一种是在函数外面 定义它;另一种是在声明变量时使用关键字 static:的 K&R C 中,只能初始化静态数组和静态结构,而 C++ Release 0(及后续版本)和 ANSI C 中,也 可以初始化自动数组和自动结构。然而,一些您可能已经发现,有些 实现还不支对自动数组和自动 结构第 9 章将详细介绍静态存储。自动存储和静态存储的关键在于:这些方法严格地限制了变量的寿命。 变量可能存在于程序的整个生命周期(静态变量),也可能只是在特定函数被执行时存在(自动变量)。 符提供了一种比自动变量和静态变量更灵活的方法。它们管理了一个内存池,这在 C++ 中被 这使得跟踪新分配内存的位置更困难。 如果没有调用 delete,则即使包含指针的内存由于2.静态存储3.动态存储new 和 delete 运算称为自由存储空间(free store)或堆(heap)。该内存池同用于静态变量和自动变量的内存是分开的。程序清单 4.22 表明,new 和 delete 让您能够在一个函数中分配内存,而在另一个函数中释放它。因此,数据的生命周期不完全受程序或函数的生存时间控制。与使用常规变量相比,使用 new 和 delete 让程序员对程序如何使用内存有更大的控制权。然而,内存管理也更复杂了。在栈中,自动添加和删除机制使得占用的内存总是连续的, 但 new 和 delete 的相互影响可能导致占用的自由存储区不连续,这使得跟踪新分配内存的位置更困难。
4.9 类型组合
4.10 数组的替代品
4.11 总结
数组、结构和指针是 C++的 3 种复合类型。数组可以在一个数据对象中存储多个同种类型的值。通过 使用索引或下标,可以访问数组中各个元素。结构可以将多个不同类型的值存储在同一个数据对象中,可以使用成员关系运算符(.)来访问其中的成员。使用结构的第一步是创建结构模板,它定义结构存储了哪些成员。模板的名称将成为新类型的标识符,然后就可以声明这种类型的结构变量。共用体可以存储一个值,但是这个值可以是不同的类型,成员名指出了使用的模式。指针是被设计用来存储地址的变量。我们说,指针指向它存储的地址。指针声明指出了指针指向的对 象的类型。对指针应用解除引用运算符,将得到指针指向的位置中的值。系列字符。字符串可用引号括起的字符串常量表示,其中隐式包含了结 尾的空字符。可以将字符串存储在 char 数组中,可以用被初始化为指向字符串的 char 指针表示字符串。函数 strlen( )返回字符串的长度,其中不包括空字符。函数 strcpy( )将字符串从一个位置复制到另一个位置。在使用这些函数时,应当包含头文件 cstring 或 string.h。头文件 string 支持的 C++ strin 类提供了另一种对用户更友好的字符串处理方法。具体地说,string 对象将根据要存储的字符串自动调整其大小,用户可以使用赋值运算符来复制字符串。new 运算符允许在程序运行时为数据对象请求内存。该运算符返回获得内存的地址,可以将这个地址赋给一个指针,程序将只能使用该指针来访问这块内存。如果数据对象是简单变量,则可以使用解除引用 运算符 new 何时将内存归还给内存池。自动变量是在函数中声明的变量,而静态变量是在函数外部或者使用关键字 static 声明的变量,这两种变量都不太灵 字符串是以空字符为结尾的一来获得其值;如果数据对象是数组,则可以像使用数组名那样使用指针来访问元素;如果数据 对象是结构,则可以用指针解除引用运算符(->)来访问其成员。指针和数组紧密相关。如果 ar 是数组名,则表达式 ar[i]被解释为*(ar + i),其中数组名被解释为数组 第一个元素的地址。这样,数组名的作用和指针相同。反过来,可以使用数组表示法,通过指针名来访问 分配的数组中的元素。
运算符 new 和 delete 允许显式控制何时给数据对象分配内存,运算符new和delete允许显式控制何时给数据对象分配内存,何时将内存归还给内存池。自动变量是
在函数中声明的变量,而静态变量是在函数外部或者使用关键字saⅵc声明的变量,这两种变量都不太灵活。自动变量在程序执行到其所属的代码块(通常是函数定义)时产生,在离开该代码块时终止。静态变量在整个程序周期内都存在。
C++98新增的标准模板库(STL)提供了模板类vector,.它是动态数组的替代品。C++11提供了模板类array,它是定长数组的替代品。
练习题