c++ Primer Plus笔记

1.第4章 复合类型

4.2字符串

4.2.2在数组中使用字符串

  1. strlen()函数返回的是存储在数组中的字符串长度,而不是数组本身的长度。另外,strlen()只计算可见的字符,而不把空字符计算在内。例如:int name1[15] = "Basicman";则strlen(name1) = 8。

4.2.3字符串输入

#include <iostream>
using namespace std;
int main(void)
{
	const int Arsize = 20;
	char name[Arsize];
	char desert[Arsize];

	cout << "Enter your name:\n";
	cin >> name;
	cout << "Enter your favorite desert:\n";
	cin >> desert;
	cout << "I have some delicious " << desert;
	cout << " for you." << name << endl;

	system("pause");
	return 0;
}

cin使用空白(空格、制表符、换行符)来确定字符串的结束位置。

4.2.4每次读取一行字符串输入

getline()和get()都读取一行输入,直到达到换行符。随后getline()将丢弃换行符,而get将换行符保留在输入序列中。

1.面向行的输入getline()

语法:cin.getline(数组名称,字符数);

例如,假设要使用getline()将姓名读入到一个包含20个元素的name数组中,cin.getline(name,20);字符数为20,则函数最多读取19个字符,余下的空间用于存储自动在结尾处添加的空字符。

#include <iostream>
using namespace std;
int main(void)
{
	const int Arsize = 20;
	char name[Arsize];
	char desert[Arsize];

	cout << "Enter your name:\n";
	//cin >> name;
	cin.getline(name, Arsize);
	cout << "Enter your favorite desert:\n";
	//cin >> desert;
	cin.getline(desert, Arsize);
	cout << "I have some delicious " << desert;
	cout << " for you." << name << endl;

	system("pause");
	return 0;
}

getline()函数每次读取一行,它通过换行符来确定行尾,但不保存换行符。相反,在存储字符串时,用空字符来替换换行符。

2.面向行的输入:get()

get()不丢弃换行符,将其留在输入队列中。假设调用两次get():

cin.get(name,Arsize);

cin.get(desert,Arsize);          //a problem

第一次调用后,换行符留在输入队列中,第二次调用看到的第一个字符便是换行符。因此get()认为已达行尾,而没有发现任何可读取的内容。

解决方式:

1.cin.get(name,Arsize);

   cin.get();

   cin.get(desert,Arsize);

2.cin.get(name,Arsize).get();

   cin.get(desert,Arsize).get();

3.空行及其他问题

get()读取空行后将设置失效位,接下来的输入将被阻断,但可以使用cin.clear();恢复输入。

4.混合输入字符串和数字

#include <iostream>
using namespace std;
int main(void)
{
	cout << "What year was your house built?" << endl;
	int year;
	cin >> year;
	cout << "what is its street address?" << endl;
	char address[80];
	cin.getline(address, 80);
	cout << "Year built:" << year << endl;
	cout << "address:" << address << endl;
	cout << "Done" << endl;

	system("pause");
	return 0;
}

解决方法:在读取地址之前先读取并丢弃换行符。

1.cin >>year;

  cin.get();              //or cin.get(ch);

2.(cin>>year).get();        //or (cin>>year).get(ch);

4.3string类简介

4.3.2赋值、拼接和附加

1.不能将一个数组赋给另一个数组,但可以将一个string对象 赋给另一个string对象。

例如:char charr1[20];char charr2[20] = "jaguar"; charr1 = charr2;     //×

          string str1; string str2 = "panther"; str1 = str2;   //√

2.string类简化了字符串合并操作。可以用运算符+将两个string对象合并起来,还可以使用运算符+=将字符串附加到string对象的末尾。

4.5共用体(P94、P95)

能够存储不同的数据类型,但只能同时存储一种类型。共用体常用来节省内存。

4.6枚举

1.设置枚举变量的值

  1. 可以使用赋值运算符显式地设置枚举变量的值。enum bits{one = 1,two = 2,four = 4,eight = 8};
  2. 指定的值必须是整数。也可以只显式地定义其中一些变量的值。enum big{fist,second =100,third};first默认为0,后面没有初始化的枚举变量的值比前面的枚举变量大1。因此third值为101。
  3. 可以创建多个值相同的枚举量。enum big{zero,null = 0,one,numero_nuo = 1};其中,zero和null都为0,one和numero_nuo都为1。

2.枚举的取值范围

上限:找到枚举量的最大值,找到大于最大值的最小的2的幂,将它减去1,得到上限。如,最大枚举值是101,则在2的幂中,比这个数大的最小值为128,因此取值范围上限为127。

下限:找到枚举量的最小值。如果它大于等于0,下限为0。如果是负数,与寻找上限方式相同,但最后加上负号。例如,最小枚举量为-6,而比它小的、最大的2的幂是-8,因此下限为-7。

4.7指针和自由存储空间

4.7.4使用new来分配内存

  1. typeName *pointer_name = new typeName;例如int *pn = new int;需要在两个地方指定数据类型:用来指定需要什么样的内存和用来声明合适的指针。
  2. 常规变量声明分配内存块:int higgens;int *pt = &higgens;   new分配内存块:int *pn = new int;new从堆区中分配内存。

4.7.5使用delete释放内存

1.int *ps = new int;   //allocate memory with new

.........                     //use the memory

delete ps;           //free memory

2.释放ps指向的内存,但不会删除ps指针本身,例如,可以将ps重新指向另一个新分配的内存块。

内存泄漏:不配对使用new和delete,一直new而不释放,被分配的内存再也无法使用。

3.不能释放已经释放的内存。

4.不能使用delete释放声明变量所获得的内存,只能用来释放new分配的内存。

4.7.6使用new来创建动态数组

静态联编:在编译时给数组分配内存。

动态联编:在运行阶段创建需要的数组并选择长度。动态数组。

1.使用new来创建动态数组

int *psome =  new int [10]; //new元素返回第一个元素的地址,该地址被赋值给指针psome。

delete [] psome;                //方括号告诉元素释放整个数组,而不仅仅是指针指向的元素。

2.使用new和delete应遵守的规则

  1. 不要使用delete来释放不是new分配的内存。
  2. 不要使用delete释放同一个内存块两次。
  3. 如果使用new[]为数组分配内存,则应使用delete [] 来释放。
  4. 对控制指针应用delete 是安全的。

3.使用动态数组

访问动态数组:将指针当作数组名即可。int *psome =  new int [10];则第一个元素psome[0],第二个元素psome[1]..........

4.8指针、数组和指针算术

1.将整数变量加1后,其值将增加1。但将指针变量加1后,增加的量等于它所指向类型的字节数

2.arrayname[i] = *(arrayname + i)          pointername[i] = *(pointername + i)

3.数组名和指针名区别:

(1)可以修改指针的值,而数组名是常量。

      pointername = pointername+1; //vaild

      arrayname = arrayname+1;           //not allowed

(2)对数组应用sizeof()运算符得到的是数组的长度,而对指针应用sizeof()得到的是指针的长度。

4.8.4使用new来创建动态结构

1.创建结构:  inflatable *ps = new inflatable;   将足以存储inflatable结构的一块可用内存的地址赋给ps。

2.访问结构成员:如果标识符是结构名,则使用句点运算符。如果标志符是指向结构的指针,则使用箭头运算符。还有一种方法是,如果ps是指向结构的指针,则*ps就是被指向的值——结构本身,因此(*ps).price是该结构的price成员。

3.一个使用new和delete的示例


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
char* getname(void)
{
	char temp[80];
	cout << "Enter the last name:";
	cin >> temp;
	char* pn = new char[strlen(temp) +1];
	strcpy(pn, temp); //copy string into smaller space
	return pn;
}
int main(void)
{
	char* name;

	name = getname();
	cout << name << " at " << (int*)name << endl;
	delete[] name;

	name = getname();
	cout << name << " at " << (int*)name << endl;
	delete[] name;

	system("pause");
	return 0;
}

getname()函数返回一个指向输入字符串的指针。该函数将输入读入到一个大型的临时数组中,然后使用new创建一个刚好嫩刚好能存储该输入字符串的内存块,并返回一个指向该内存块的指针。(节省内存)

4.8.5自动存储、静态存储和动态存储

c++3种管理数据内存的方式:自动存储、静态存储、动态存储。

1.自动存储:局部变量   在所属函数被调用时自动产生,在该函数结束时消亡    通常存储在栈中 后进先出   在程序执行过程中栈不断地增大和缩小

2.静态存储:整个程序执行期间都存在  静态变量有两种:一种是在函数外面定义它,另一种是在声明变量时使用关键字stattic。

3.动态存储: 堆区

4.10数组的替代品

4.10.1模板类vector

模板类vector  类似于string类,也是一种动态数组。基本上,他是使用new创建动态数组的替代品。

  1. 必须包含头文件   #include
  2. 语法:  vector  vt;  n_elem可以是整型常量,也可以是整型变量。例如,vector  vd;

4.10.2模板类array

  1. 头文件 #include
  2. 语法:array arr;   n_elem不能是变量,只能是常量。

4.10.3比较数组、vector对象和array对象

#include <iostream>
#include <vector>
#include <array>
using namespace std;
int main(void)
{
	//数组
	double a1[4] = { 1.2,2.4,3.6,4.8 };
	//vector对象
	vector<double> a2(4);
	a2[0] = 1.0 / 3.0;
	a2[1] = 1.0 / 5.0;
	a2[2] = 1.0 / 7.0;
	a2[3] = 1.0 / 9.0;

	//array对象
	array<double, 4> a3 = { 3.14,2.72,1.62,1.41 };
	array<double, 4>a4;
	a4 = a3;

	cout << "a1[2]:" << a1[2] << " at " << &a1[2] << endl;
	cout << "a2[2]:" << a1[2] << " at " << &a2[2] << endl;
	cout << "a3[2]:" << a1[2] << " at " << &a3[2] << endl;
	cout << "a4[2]:" << a1[2] << " at " << &a4[2] << endl;

	a1[-2] = 20.2;
	cout << "a1[-2]:" << a1[-2] << " at " << &a1[-2] << endl;
	cout << "a3[2]:" << a3[2] << " at " << &a3[2] << endl;
	cout << "a4[2]:" 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值