C++ Primer Plus第六版-第四章-学习笔记

C++ Primer Plus第六版-第四章-学习笔记

4.1 数组

C++允许在声明语句中初始化数组元素。

int yamcosts[3] = {20, 30, 5};

数组的初始化规则

只有在定义数组时才能使用初始化,以后就不能使用了;
然而,可以使用下标分别给数组中的元素赋值;
如果对数组中的部分元素初始化,则编译器将把其他元素设置为0;
数组可以使用列表初始化,初始化数组时,可以省略等号:

double earning[4] {1.2e4, 1.6e4, 1.1e4, 1.7e4};  // okey with C++11

4.2 字符串

字符串是存储在内存的连续字节中的一系列字符。C++处理字符串的方式有两种:

1. C-风格字符串

以空字符结尾,空字符被写作\0,C++有很多处理字符串的函数,其中包括cout使用的那些函数。它们都逐个处理字符串中的字符,直到到达空字符为止。
将数组初始化为字符串时,必须记住加上空字符。用引号括起来的字符串(字符串常量或字符串字面值)初始化数组,不用担心这个问题,因为其隐式包含结尾的空字符。
"S"表示由字符S和\0组成的字符串。

拼接字符串常量

任何两个由空白(空格、制表符和换行符)分割的字符串常量都将自动拼接成一个。

在数组中使用字符串
  • 将数组初始化为字符串常量
  • 将键盘或文件输入读入到数组中
    每次读取一行字符串输入
    cin使用空白(空格、制表符和换行符)来确定字符串的结束位置,这意味着用cin 每次只能读取一个单词,若要一次读取多个单词,就要考虑输入一行数据的方法。
getline()
cin.getline(name, num) //name为数组名,num为读取的字符数(包含最后一个空字符\0)
getline()成员函数在读取指定数目的字符或遇到换行符时停止读取
get()
cin.get(name, num) //与getline()用法类似,区别在于get()读取到换行符会把它留在输入队列
还好有不带参数的cin.get()可以跳过换行符,直接读取下一个字符,这样就为解决连续调用
cin.get()或cin.getline()时由于换行符留在输入队列中而导致的不能继续读取输入的问题
输入空行的问题,后面章节再做具体讨论
混合输入字符串和数字
问题原因在于cin和cin.get(name, num)会将回车键生成的换行符留在输入队列,而对于行输入,
遇到换行符会停止读取
所以用不带参数的cin.get()解决这个问题(跳过换行符)

4.3 string类简介

使用string类,必须在程序中包含头文件string
类设计让程序能够自动处理string的大小
使用string对象比使用数组更方便、更安全。从理论上讲,可以将char数组视为一组用于存储一个字符串的char存储单元,而string类变量是一个表示字符串的实体。

C++11允许列表初始化用于C-风格字符串和string对象
不能将一个数组赋值给另一个数组,但可以将一个string对象赋给另一个string对象

string类 I/O

将一行输入读取到string对象中

getline(cin, str)

其他形式的字符串字面值

除char类型外,C++还有类型wchar_t;C++11新增了类型char16_t 和char32_t 。
C++分别使用L、u、U表示

C++11新增的另一种类型是原始(raw)字符串

原始字符串将 “( 和 )” 用作定界符,并使用前缀R来标识原始字符串

4.4 结构简介

定义结构描述
创建结构变量
C++11也支持将列表初始化用于结构
也可以将string 类作为成员
其他结构属性

还可以使用赋值运算符将结构赋给另一个同类型的结构

结构中的位字段

与C语言一样,C++也允许指定占用特定位数的结构成员,这使得创建与某个硬件设备上的寄存器对应的数据结构非常方便。

4.5 共用体

共用体(union)是一种数据格式,它能够存储不同的数据类型,但只能同时存储其中的一种类型。
共用体常用于操作系统数据结构或硬件数据结构。

4.6 枚举

enum spectrum {red, orange, yellow, green, blue, violet, indigo, ultraviolet};

spectrum被称为枚举,就像struct 变量被称为结构一样

spectrum band; //可以用枚举名来声明这种类型的变量,只能将定义枚举时使用的枚举量赋给这种枚举的变量

对于枚举只定义了赋值运算符
枚举量是整形,可被提升为int类型,但int类型不能自动转为枚举类型;

int color = blue; //valid
band = 3; //invalid
color = 3 + red; //valid
如果int值是有效的,则可以通过强制类型转换将它赋给枚举变量;
band = spectrum(3);  //typecast 3 to type spectrum
设置枚举量的值

默认情况下,将整数值赋给枚举量,第一个枚举量的值为0,后面没有被初始化的枚举量的值比其前面的枚举量大1。可以创建多个值相同的枚举量。

枚举的取值范围

取值范围定义如下:
上限 找到最大值,则大于最大值的最小的2的幂,减去1,得到的便是上限;
下限 找到最小值,如果最小值不小于0,则下限为0;否则与上限相同的找法,最后加负号;

4.7 指针和自由存储空间

计算机程序存储数据的三种属性:

  • 信息存储在何处
  • 存储的值为多少
  • 存储的信息是什么类型
    指针是一个变量,其存储的是值的地址
    *运算符被称为间接值或解除引用

声明和初始化指针

指针声明必须指定指针指向的数据类型

int* ptr; //int*是一种复合类型,是指向int的指针
int higgens = 5;
int* pt = &higgens;  //可以在声明语句时初始化指针,被初始化的是指针
一定要在对指针应用解除引用运算符(*)之前,将指针初始化为一个确定的、适当的地址
int* pt;
pt = (int*) 0xB8000000;  //要将数字作为地址来使用,应通过强制类型转换将数字转换为适当的地址类型

用new来分配内存

指针真正的用武之地在于,在运行阶段分配未命名的内存以存储值

int* pn = new int; // new根据类型确定需要的内存,找到内存,返回地址,赋给pn,pn是被声明指向int的指针
typeName* pointer_name = new typeName //为一个数据对象(结构或基本类型)获得并指定分配内存的通用格式

new分配的内存在堆或自由存储区,而常规变量的值存储在栈中
配对使用delete释放内存

int* ps = new int;
delete ps;

使用new来创建动态数组

在编译时给数组分配内存被称为静态联编;在程序运行时选择数组的长度,称为动态联编。

int* psome = new int [10];
delete [] psome;
type_name* pointer_name = new type_name [num_elements]; //为数组分配内存的通用格式
使用动态数组

把指针当作数组名使用即可
指针和数组名的差别:

double* p3 = new double[3];
p3 = p3 + 1; //可以改变指针的值,但不能修改数组名的值

4.8 指针、数组和指针算术

对数组应用sizeof运算符得到的是数组的长度,而对指针应用sizeof得到的是指针的长度
数组的地址
数组名被解释为其第一个元素的地址,而对数组应用地址运算符时,得到的是整个数组的地址

short tell[10];
cout << tell << endl; // display &tell[0]
cout << &tell << endl; // display address of whole array
short (*pas)[20] = &tell; //pas points to array of 20 shorts

给指针赋值
应将内存地址赋给指针。可以对变量名应用&运算符,来获得被命名的内存地址,new 运算符返回未被命名的内存的地址。

double* pn;
double* pa;
double buddle = 3.2;
pn = &buddle;
pa = new double[30]; // assign address of 1st element  of array of 30 double to pa

指针算术

C++允许将指针和整数相加。
加1的结果等于原来的地址值加上指向对象占用的总字节数
还可以将一个指针减去另一个指针,得到两个元素的间隔。(仅当两个元素指向同一个数组)

数组的静态和动态联编

使用数组声明来创建数组时,将采用静态联编,即数组的长度将在编译时设置;
使用new[ ]运算符创建数组时,将采用动态联编(动态数组),即将在运行时为数组分配空间,其长度也将在运行时设置。使用完这种数组后,应使用delete[ ]释放其占用的内存。

数组表示法和指针表示法

使用方括号数组表示法等同于对指针解除引用:

int* pt = new int [10];
*pt = 5; // set element number 0 to 5
pt[0] = 6; // reset element numner 0 to 6

指针和字符串

如果给cout提供一个字符的地址,则它将从该字符开始打印,直到遇到空字符为止。
在cout和多数C++表达式中,char数组名、char指针以及用引号括起的字符串常量都被解释为字符串第一个字符的地址。
一般来说,如果给cout提供一个指针,它将打印地址。但如果指针的类型为char* ,则cout将显示指向的字符串。如果要显示字符串的地址,则必须将这种指针强制转化为另一种类型。
获得字符串的副本:

char* ps;
ps = new char[strlen(animal) + 1]; //get new storage
strcpy(ps, animal); //copy string to new storage

使用new创建动态结构

箭头结构运算符(->)
如果结构标识符是结构名,则使用句点运算符;如果标识符是指向结构的指针,则使用箭头运算符。
自动存储和静态存储变量存储在栈中,动态存储变量存在自由存储空间或堆中。动态存储更加灵活,使用new和delete让程序员对程序如何使用内存有更大的控制权。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑着的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值