C++ Primer Plus 第四章之知识梳理

4.1数组

  1. 需要声明数组的类型,数组名,数组中的元素数。
  2. 下标从0开始,注意有效下标值的重要性。
  3. 数组的初始化
int hand[4];
hand[4] = {5,6,7,7};//不允许
int cost[4] = {1,2,3,4};//可以
hand = cost;//不允许
long hands[100] = {0};//将全部元素都赋值为0

如果只对数组的一部分进行赋值,则其他剩下的元素则自动被赋值为0

4.2字符串

  1. 区分’s’和“s”,一个是字符常量,一个是字符串
  2. 用引号括起的字符串隐式地包括结尾的空字符,所以在字符串数组初始化时,尽量用“”双引号进行初始化。
  3. 字符串拼接,拼接之间不会添加空格,是紧跟在前一个字符串后面的
  4. 字符串存储到数组中,可以将数组初始化为字符串常量,或者从键盘或文件内读入。
  5. sizeof和strlen的区别
    strlen()函数在cstring 头文件中,计算的是存储在数组中的字符串的长度,而不是数组本身的长度,且只计算可见字符,不把空字符计算在内
    sizeof运算符指出的整个数组的长度,如15字节。
    注意:数组的长度不能短于strlen(字符串)+1

4.2.1字符串的读入

#include<iostream>
using namespace std;
int main()
{
	const int ArSize = 20;
	char name[ArSize];
	char dessert[ArSize];
	
	cout<<"Enter your name:\n";
	cin>>name;
	cout<<"Enter your favorite dessert:\n";
	cin>>dessert;
	cout<<"I have some "<<dessert;
	cout<<" for you,"<<name<<".\n";
	return 0;
}

上面代码会出现的问题是:
在这里插入图片描述
还没有输入完,程序就把它显示出来了。
原因:cin使用空白(空格、制表符和换行符)来确定字符串的结束位置。
为解决这个问题,引入getline()和get()

4.2.2 getline()和get()

getline()
每次只读取一行,通过换行符来确定行尾,但不保存换行符。存储时,换行符被替换为空字符。
get()
并不再读取并丢弃换行符,而是保存在输入队列中

cin.get(name,Arsize);
cin.get(dessert,Arsize);//有问题


cin.get(name,Arsize);
cin.get();
cin.get(dessert,Arsize);//这种可以


cin.get(name,Arsize).get();
cin.get(dessert,Arsize).get();//这种也可以

对比总结:
getline()用起来更加简便,但是get()更容易检查错误,可以知道停止读取是因为已经读取了整行还是因为数组填满了。

4.2.3 字符串输入的空行问题

#include<iostream>
using namespace std;
int main()
{
	const int ArSize = 20;
	char address[ArSize];

	cout<<"Enter your year:\n";
	int year;
	cin>>year;
	cout<<"Enter your favorite address:\n";
	cin.get();//不加这一行没办法输入地址
	//或者
	//(cin>>year).get();
	cin.getline(address,ArSize); 
	cout<<"My year :"<<year<<endl;
	cout<<"My address :"<<address<<".\n";
	return 0;
}

因为输入year之后,回车,cin.getline(address,ArSize); 会把上一个结束的回车符当成下一个输入,误认为空字符行。所以中间加个cin.get();把空字符读取掉。

4.3 String类

  1. 包含在#include中
  2. 字符数组之间不可以相互赋值,但是可以将一个String对象赋值给另一个String对象
  3. 有着简便的字符串合并操作,使用运算符+,+=
#include<iostream>
#include<string>
#include<cstring>
using namespace std;

int main(){
	
	char c[20];
	string str;
	string ss;
	
	cout<<"输入前数组c的长度"<<strlen(c)<<endl;
	cout<<"输入前str的字符串长度"<<str.size()<<endl;
	cout<<"输入前ss的字符串长度"<<ss.size()<<endl;
	
	cin.getline(c,20);
	getline(cin,str);
	cin>>ss;
	
	cout<<"输入后数组c的长度"<<strlen(c)<<endl;
	cout<<"输入后str的字符串长度"<<str.size()<<endl;
	cout<<"输入后ss的字符串长度"<<ss.size()<<endl;
	
	cout<<"数组c :"<<c<<endl;
	cout<<"str :"<<str<<endl;
	cout<<"ss :"<<ss<<endl;
	
	return 0;
} 

输出结果
在这里插入图片描述
分析

  1. 对于字符数组,初始化的数组的内容是未定义的,其次函数strlen()从数组的第一个元素开始计算字节数,直到遇到空字符。在这个例子中,在数组末尾之前的字节都遇到空字符。即,对于未被初始化的数据,第一个空字符出现的位置是随机的,所以得到的长度与此不同。
  2. 未被初始化的string对象的长度被自动设置为0.
  3. getline(cin,str);//可以输入string对象
    cin>>ss;//cin也可以输入

4.4 结构

1.关键字:struct,同一个结构可以存储多个类型的数据。
2.提倡使用外部结构声明,不提倡使用外部变量。
3.结构数组
4.结构的初始化

4.5 共用体

1.关键字:union, 与结构体的区别在于,能存储不同的数据类型,但只能同时存储其中一个类型。
2.常用于,当数据项使用两种或多种格式时,可节省空间。
3.常用于操作系统数据结构或硬件数据结构。
4.可以用于嵌入式编程

4.6 枚举

1.关键字 enum
2.创建符号常量的方式,常用来定义相关的符号常量。例如,switch语句中使用符号常量
3.枚举的值的设置,及取值范围。

4.7 指针

1.声明语句指出值的类型和符号名
2.指针存储的是值的地址,不是值
3.对于每个指针变量名都必须使用一个*
int *p1,p2//p1是指针,p2是int变量
4.指针!!!只分配了存储地址的内存,没有分配该地址所指的数据的内存。所以!在使用解除引用运算符(*P)时,一定要将指针初始化为一个确定的、适当的地址。
5.指针的真正用武之地在于,在运行阶段分配未命名的内存以存储值
6.用new来分配内存
int * p1 = new int;

  • *p1 = 1001;
    7.用delete释放内存。new和delete要配对地使用
	int * psome = new int [10];
	delete [] psome;
	int * pt = new int;
	delete pt;

有[]的时候,delete也要[],代表释放整个数组,而不是仅指针指向的元素。new的时候没有[],delete的时候也不要[]

4.8

4.8.3 指针和字符串

在将字符串读入程序时,应使用已分配的内存地址,可以是数组名,也可以是new初始化过的指针

4.8.4 使用new创建动态结构

1.创建结构,需要同时使用结构类型和new
inflate * p = new inflate;

p->name;
(*p).volume;

当结构标识符是结构名,用句点运算符;当标识符是指向结构的指针,则使用箭头运算符。

4.10 模板类vector和array

模板类vector

是使用new创建动态数组的替代品

头文件:#include <vector>
例子:vector<int> vi;
vector<double> vd(n);//参数n可以是整型变量也可以是整型常量

模板类array

与数组一样,array对象的长度是固定的,也使用栈(静态内存分配),效率跟数组相同,但是更方便,更安全

头文件:#include<array>
例子:array<int,4> ai;
array<double,5> ad={1,2,3,4,5};//与vector不同的是
//参数不能是变量

vector对象、array对象、数组三者比较

  1. 三者都可以用标准数组表示法来访问各个元素
  2. array对象和数组存储再相同的内存区域(即栈)中,vector对象存储在另一个区域(自由存储区或堆)中
  3. 可以将array对象赋值给另一个array对象,对于数组,则必须逐元素复制
  4. 在vector和array对象中用成员函数at()比用中括号表示法的优点是时,可以在运行期间捕获非法索引,而程序默认中断,但额外检查的代价是运行时间更长。
发布了9 篇原创文章 · 获赞 0 · 访问量 1801

猜你喜欢

转载自blog.csdn.net/weixin_46021869/article/details/104043188