C++ Primer Plus阅读笔记第四章数组,字符串和指针_c++primer plus数组的地址在第几章

第四章 符合类型

4.1 数组

数组的初始化规则:

只有在定义数组的时候才能初始化,此后就不能使用了。也不能将一个数组赋值给另一个数组。

int cards[4]={3,1,5,7};	//okay
int hand[4];	//okay
hand[4]={5,6,7,8}; 	//not allowed
hand=cards;		//not allowed

可以这样计算得出数组元素的个数:利用数组名的大小除以数组元素的大小

short things[]={1,3,4,6};
int num_elements=sizeof things / sizeof (short);

C++11中的列表初始化新增了一些功能:

1.初始化数组时可以省略等号=

double earnings[4]{1.2e4, 1.6e4, 1.1e4, 1.7e4};

2.可不在大括号内包含任何东西,这将把所有元素都设置为零

unsigned int counts[10]={};
float balances[100]{};

3.列表初始化禁止缩窄转换

long plifs[]={25,92,3.0};	//not allowed

不能把3.0浮点型转换成整形,这属于缩窄操作。

4.2 字符串

1.C-风格字符串具有一种特殊的性质:以空字符结尾,空字符被写作\0,其ASCII码为0,用来标记字符串的结尾。

char dog[8]={'b','e','a','u','x',' ','I','I'};	//not a string
char cat[8]={'f','a','t','e','s','s','a','\0'};	//a string

这两个都是char类型的数组,但只有第二个才是字符串

那么这种赋值比较复杂,还比较难输入。这就可以使用另一种方法将字符数组初始化为字符串。“ ”,这种字符串被称为字符串常量,或字符串字面值。

char bird[11]="Mr. Cheeps";	//\0 is understood
char fish[]="Bubbles";

用引号括起的字符串隐式地包括结尾的空字符,因此不用显示地包括它。

4.3 字符串输入

为了解决当遇到空格就提前结束的情况,提出了面向行输入的命令。

我们发现在cin输入字符串的时候,它仅仅是面向单词的输入方式。而我们在想输入字符串的时候,是想让它面向行的输入方式。

比较nb的是:istream中的类(如cin)提供了一些面向行的类成员函数:getline()和get().这两个函数都读取一行输入,直到到达换行符。

不同点:getline()将丢弃换行符,而get()将换行符保留在输入序列中。

1.面向行的输入:getline()

getline()函数读取整行,它使用通过回车键输入的换行符来确定输入结尾。

cin.getline()该函数有两个参数,第一个参数是用来存储输入行的数组的名称,第二个参数是要读取的字符数。如果字符数是20的话,那么最多只能输入19个字符,余下的空间用于存储自动在结尾处添加的空字符。

char name[20];
cin.getline(name,20);

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

get()工作方式与getline()类似,接收的参数也都相同。当不同点是:get()并不再读取并丢弃换行符,而是将其留在输入队列中。

假如我们这样操作:

cin.get(name,20);
cin.get(dessert,20);	//a problem

由于第一次调用后,换行符被留在了输入队列中,所以第二次调用时看到的第一个字符便是换行符。因此get()以为到了行尾,不再发现任何可读取的内容。

nb的是:get()有另外一种变体,使用不带任何参数的cin.get()调用可读取下一个字符。

cin.get(name ,20);
cin.get();	//便可跳过换行符
cin.get(dessert,20);	//read second line

或者可以这样写:

cin.get(name,20).get();

3.混合输入字符串和数字出现的问题

当cin>>year;

之后会把换行符留在输入队列中,所以使用完cin>>year;之后,应该在后面添加一句:

cin.get();	//跳过换行符

4.string类简介
string对字符串的处理和c-风格的字符串之间的对比:

c-风格的字符串头文件#include

c-风格之间的一般操作:

//首先声明两个c风格的字符串数组
char charr1[20];
char charr2[20];

//复制字符串数组到另一个字符串数组中去
strcpy(charr1,charr2);	//copy charr2 to charr1

//拼接字符串数组
strcat(charr1,charr2);	//append contents of charr2 to charr1

//查看字符串数组中的大小
int len=strlen(charr1);

string 一般的操作为:

//声明两个string类型的变量
string str1;
string str2="nihao";

//复制字符串变量到另一个字符串变量中去
str1=str2;

//拼接字符串
str2+="xiaoming";

string str3=str2+str1;

//确定字符串中字符数
int len1=str1.size();

5.string类型的变量进行面向行的输入

前面所看到的cin.getline() ,cin.get()都是面向c-风格类型的字符串数组

接下来开始解析面向string类型的字符串变量进行面向行变量的输入赋值。

string name1;

getline(cin,name1);

4.4 结构简介

1.创建结构分为两步:定义结构和创建结构变量

比如定义结构:

struct inflatable
{
    char name[20];
    float volume;
    double price;
};

定义:

inflatable gust={"Glorious Gloria",1.99,29.99};
//访问结构成员
cout <<gust.name<<gust.volume<<gust.price<<endl;

2.作用域

注意当外部声明的时候,可以用在文件的所有函数中。作用域是整个cpp从top到down的位置。

当内部声明的时候,是作用域是声明所在函数的位置内部。

3.其他结构属性

可以使用赋值运算符(=)将结构赋给另一个同类的结构,这样结构中的每个成员都将被设置为另一个结构中相对应成员的值。

struct inflatable
{
    char name[20];
    float volume;
    double price;
}

inflatalbe bouquet={
    "sunflowers",
    0.20,
    12.49
};
inflatable choice;

choice=bouquet;		//同类结构变量可以赋值

也可以同时定义结构和创建结构变量,如:

struct perks
{
    int key_number;
    char car[12];
}mr_smith, ms_jones;//这里声明了两个结构变量

4.结构数组

这里定义一个inflatable类型的数组,里面的每一个变量都是inflatable类型。

inflatable guests[2]
{
    {"Bambi",0.5,21.99},
    {"Godzilla",2000,565.99}
};

4.5 共用体

共用体(union)是一种数据格式,他能够存储不同的数据类型,但只能同时存储其中的一种类型。

由于共用体每次只能存储一个值,因此他必须有足够的空间来存储最大的成员,所以共用体的长度为其最大成员的长度。

声明:

union one4all
{
    int int_val;
    long long_val;
    double double_val;
};

可以使用one4all变量存储int、long或double,条件是在不同的时间进行。

one4all pail;
pail.int_val=15;
cout <<pail.int_val;

pail.double_val=1.38;	//这个时候,上次存储的int\_val已经失效了。
cout<<pail.double_val;	

1.使用共用体的场景

共用体常用于节省内存。另外,共用体常用操作系统数据结构或硬件数据结构。

4.6 指针和自由存储空间

关于面向对象编程和传统的过程性编程的区别的一些思考:

面向对象编程与传统的过程性编程的区别在于,OPP强调的是在运行阶段(而不是编译阶段)进行决策。运行阶段指的是程序正在运行时,编译阶段指的是编译器将程序组合起来时。运行阶段决策提供了灵活性。

比如:考虑为数组分配内存的情况。

传统的方法时声明一个数组,要在c++中声明数组,必须指定数组的长度。因此,数组长度在程序编译时就设定好了,这就是编译阶段决策。

OOP通过将这样的决策推迟到运行阶段运行,使程序更灵活,在程序运行后,可以这次告诉它只需要20个元素,而话可以下次告诉它需要200个元素。

总之,使用OOP,您可能在运行阶段确定数组的长度,为使用这种方法,语言必须允许在程序运行时创建数组。

1.指针

指针名表示的是地址。*运算符被称为间接值或解除引用运算符,将其应用于指针,可以得到该地址处存储的值。

2.声明和初始化指针
//下面的声明创建一个指针(p1)和一个int变量(p2)
int\* p1,p2;

**指针的危险:**在C++中创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。

3.指针和数字

要将数字值作为地址来使用,应通过强制类型转换将数字转换为适当的地址类型。如:

int \* pt;
pt=(int \*)0xB8000000;

4.使用new来分配内存

变量是在编译时分配的有名称的内存,而指针只是为可以通过名称直接访问的内存提供了一个别名。指针真正的用武之地在于,在运行阶段分配未命名的内存以存储值。

在c-语言和C++语言中都可以使用malloc()来分配内存。但C++还有更好的方法——new运算符。

在运行阶段为一个int值分配未命名的内存,并使用指针来访问这个值。程序员要告诉new,需要为哪种数据类型分配内存,new找到一个长度正确的内存块,并返回该内存块的地址。示例:

int \* pn =new int;

new int 告诉程序,需要适合存储int的内存。new运算符根据类型来确定需要多少字节的内存。然后它找到这样的内存,并返回其地址。

对于指针,需要注意的是:new分配的内存块通常与常规变量声明分配的内存块不同,常规变量都存储在被称为栈的内存区域中,而new从被称为堆或者自由存储区的内存区域分配内存。

5.使用delete释放内存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值