C++ Primer Plus的若干收获--(二)

哎,真是不想吐槽考驾照的艰辛历程了。跑到大西郊,顶着大太阳,一天就能摸上个十几分钟二十分钟的车,简直不要太坑爹,这两天真是做的我屁股疼的不行。

。。

今天果断不去了。仅仅可惜我的大阿根廷啊,坚持到最后功亏一篑惜败于德国,枉我四点自然醒起来看了接下来的比赛。

不能不佩服诺伊尔,拉姆。博阿滕组成的后防线,让阿根廷整场没有几个有威胁的射门。祝贺我大克洛泽在职业生涯暮年能将大力神杯捧入怀中。。。

拜拜   巴西世界杯,拜拜  阿根廷,拜拜,    梅西。

2.1  字符串常量

将字符数组初始化为字符串的工作看上去冗长乏味--使用大量的单引號,且必须记住加上空字符。

不必操心,有一种更好的。将数组初始化为字符串的方法---仅仅须要使用一个用引號括起来的字符串就可以。这样的字符串被称为字符串常量,如:

<span style="font-size:14px;">char dog[8]={‘b‘,‘e‘,‘a‘,‘u‘,‘x‘,‘ ‘,‘i‘};//not  a string
char cat[8]={‘f‘,‘a‘,‘t‘,‘e‘,‘s‘,‘s‘,‘a‘,‘\0‘};//a  string

char bird[11]="Mr.Cheeps";
char fish[]="Bubbles";

</span>

有时候字符串非常长,无法放在一行。C++同意将两个引號括起来的字符串常量合并为一个。其实,不论什么两个有空白(空格,制表符和换行符)分隔的字符串常量都将自己主动拼接成一个。因此,可有例如以下的语句:

<span style="font-size:14px;">cout<<"I‘d give my right arm to be" "a great violinist.\n"
cout<<"I‘d give my right arm to be a great violinist.\n";
cout<<"I‘d give my right arm to" </span>
<span style="font-size:14px;">"be a great violinist.\n";</span>

2.2 字符串的读入  cin与getline的讨论

  • 首先来看cin是怎样完毕字符串的输入呢?因为不能通过键盘输入空字符,因此cin须要用别的方法来知道字符串的结尾位置。

    cin使用(空格、制表符和换行符)来确定字符串的结束位置。这意味着cin在读取字符串的时候仅仅能读取一个单词。读取该单词后,cin将该字符串放到数组中,并自己主动在结尾处加入空字符。
  • 显然每次读取一个单词通常不是好的选择,此时我们须要採用面向行而不是面向单词的方法。

    此时。istream类提供一些面向行的成员函数:getline()与get()。这两个函数都读取一行输入。知道到达换行符。可是二者的差别在于getline()将丢弃换行符。而get()将保留换行符在输入队列中。
  • 以下先介绍getline()函数。它读取正行并通过回车键出入换行符来确定输入队尾。

    要调用这样的方法可採用cin.get()。该函数有两个參数,第一个參数用来存储行的数组名称,第二个參数是要读取的字符数。

    比如

  • cin.getline(name,20);
  • 接下来我们来看还有一种方法。istream类有还有一个名为get()的成员函数。该函数有几种变体。当中一种的工作方式与getline()类似,它们接受的參数同样,可是差别在于它不在丢弃换行符,而是将它保留在输入队列中
    <span style="font-size:14px;">cin.get(name,ArtSize);
    cin.get(dessert,ArtSize);//此时dessert仅仅会读入一个换行符而显示为空</span>
  • 为了解决问题,get()函数提供了还有一种变体,用它来解决换行符,为读取下一行做准备
    <span style="font-size:14px;">cin.get(name,ArtSize);
    cin.get();
    cin.get(dessert,ArtSize);//ok</span>
  • 最后一种使用该函数的方法时将其拼接起来。

    之所以能够这样做的原因是cin.get(...)会返回一个cin对象,该对象随后被用来调用cin函数。

    <span style="font-size:14px;">cin.get(name,ArtSize).get();
    cin.getline(name1,ArtSize).getline(name2,ArtSize);</span>

以下给出一个比較easy错的样例,给与一下小的提醒。

<span style="font-size:14px;">#include<iostream>
int main()
{
	using namespace std;
	cout<<"What year was your house built?\n";
	int year;
	cin>>year;
	cout<<"What is its street address?\n";
	char address(80)
	cin.getline(address,80);//此时会读入回车
	cout<<"Year built:"<<year<<endl;
	cout<<"Done!\n";
	return 0;
}</span>

2.3 再谈getline

以下是一行输入到读取的代码:

<span style="font-size:14px;">cin.getline(charr,20);</span>

这样的句点表示法表明,函数getline()是istream类的一个类方法。以下是另外一行代码:

<span style="font-size:14px;">getline(cin.str);</span>

这里没有使用句点表示法,这表明这样的方法不是类方法。它将cin作为參数,支出到哪里去查找输入,其次他也没有指出字符串的长度參数。那么为何一个getline函数是istream的类方法。而还有一个不是呢?在引入string类之前非常久。c++就有istream类。因此istream类在这几的时候考虑到了其它基本类型而并没有考虑到string这样的类型。所以在istream类中有处理double int和其它类型的类方法,而没有处理string的类方法。

2.4 枚举类型

C++的enum工具提供了还有一种创建符号常量的方式,这样的方式能够替代const。它还同意定义新类型,但必须按严格的限制进行。请看以下语句:

<span style="font-size:14px;">enum spectrum{red,orand,yellow,green,blue,violet,indigo};</span>

该语句完毕了:让spectrum成为了一个新类型。它成为枚举类型;其次将red,orange,yellow等作为符号常量,它们相应整数值0~7.这些常量叫做枚举量。在默认情况下,将整数值给予枚举量,第一个枚举量的值为0。第二个为1。依次类推。

枚举变量具有以下的性质。

<span style="font-size:14px;">spectrum band;
band=blue;//valid
band=2000;//invalid,2000 not an enumerator
//对于枚举,仅仅定义了赋值运算符,详细地说没有为其定义算数运算:
band=orange;//valid
++band;//error
band=orange+red;//error
//枚举类型可被提升为整形。可是int类型不能自己主动转换为枚举类型
int color=blue;//valid,spectrum type promoted to int
band=3;//error
color=3+red;//red converted to int</span>

正如你看到那样。枚举的规则相当的严格。

实际上,枚举更经常被用来定义相关的符号常量,而不是新类型。

假设打算仅仅使用常量。而不创建枚举类型的变量,则能够省略枚举类型的名称。如:

<span style="font-size:14px;">enum{red,orange,yellow...};</span>

2.5 在使用new与delete可能会遇到的相关问题

我们知道,当须要内存时。我们能够使用new来请求,当使用完内存时,我们使用delete运算符来将其归还给内存池。在使用new与delete时,我们应当遵循下面规则:

  • 不要使用delete来释放不是new分配的内存
  • 不要使用delete来释放同一块内存
  • 假设使用new【】为数组分配内存时。应使用delete【】来释放
  • 假设使用new为一个实体分配内存时,则应使用delete(没有括号)来释放
  • 对空指针应用delete是安全的

以下简要介绍一下内存泄露或内存被耗尽:计算机可能因为没有足够的内存而无法满足new请求。在这样的情况下。new一般会引发异常。该异常会在以后解说。

在C++中。值为零的指针被称为空指针。C++确保空指针不会指向有效的数据。因此它常备用来表示运算符或函数失败。被泄露的内存将在程序的整个生命周期都不可使用;这些内存被分配出去可是无法使用。极端情况下是。内存泄露很严重,以至于应用程序所用的内存被耗光,出现内存耗尽的错误,导致程序崩溃

2.6 自己主动存储、静态存储与动态存储

  • 自己主动存储     在函数内部第一的常规变量使用自己主动存储空间被称为自己主动变量,这意味着他们在所属的函数被调用时自己主动产生,在该函数结束时消亡。

    实际上自己主动变量是一个局部变量,其作用域包括他的代码块。

    代码块是包括在花括号内的一段代码。自己主动变量常存储在栈中。这意味着在运行代码块时,当中的变量将依次增加到栈中,而在离开代码块时,将按相反的顺序释放这些变量。

  • 静态存储      静态存储是整个程序运行区间都存在的存储方式。

    是变量成为静态变量的方式有两种:一种是在函数的外面定义了它,还有一种则是使用keywordstatic

    <span style="font-size:14px;">static double fee=56.50;</span>
  • 动态存储      new与delete运算符提供了一种比自己主动变量和静态变量更灵活的方法。

    他们管理了一个内存池,这在C++中被称为自由存储空间或堆。该内存池通用于静态变量和自己主动变量的内存是分开的。因此数据的生命周期全然不受程序或函数生存时间控制。与常规变量相比,使用它们能够让程序猿对程序怎样使用内存有更大的控制权。
时间: 2024-10-12 14:48:59

C++ Primer Plus的若干收获--(二)的相关文章

C++ Primer Plus的若干收获--(八)

接下我会比较系统的介绍OOP的核心--类这个概念.可能会写的比较繁琐,比较多,但是自己理解总是好的.还记得上学期刚开始的时候老师讲的数据结构,一上来就来个LIst的一个大类,结果全班就傻了,完全不知所云(ps:博主是数学系,只学过C),然后自己就坐在图书馆借了两大本C++书开始啃了起来,大概啃了两个月才把C++学了个大概,尤其是读到类这块都是三四百行的常常的代码,看的那叫一个痛苦啊.不过自此之后就真正喜欢上这门语言了,再到之后能用C++写上个一两千行的代码,才发现之前的努力还是有收获的.好了,废

C++ Primer Plus的若干收获--(十)

明天就要回学校了,本来回家之前是有一片宏图伟志的,无奈只能抱着这可怜的十篇博客回学校了.自己马上就要大三,大学的下一半马上就要开始了,我的未来还有什么在等待着我呢,好期待!!! 10.1 友元 我们知道C++控制对类对象私有部分的访问.通常,公有类方法是唯一的途径,但是除此之外C++还提供了另外一种机制:友元.友元有三种友元函数,友元类与友元成员函数.在介绍如何成为友元前,先介绍一下为何需要友元.在为类重载二元运算符是常常需要友元.将之前的Time对象乘以实数就是这种情况. 我们之前重载了+ T

C++ Primer Plus的若干收获--(七)

这篇博文主要讲了名称空间,说实话在接触之前一直对这方面很感兴趣,现在来好好的学习一番. 7.1 新的名称空间特性 C++新增了这样一种功能,即通过定义一种新的声明区域来创建命名的名称空间,这样做的目的之一是提供一个声明名称的区域.一个名称空间的名称不会与另外一个空间的名称发生冲突,同时允许程序的其他部分使用该名称中声明的东西.比如,下面的代码使用关键字namespace创建了名称空间: namespace Jack { double pail; void fetch(); int pal; st

C++ Primer Plus的若干收获--(九)

这篇博文我接着上一篇来写,相同讲一些关于类的一些基础知识. 本篇将会继续使用上篇的股票类STock,这里给出接口 ifndef STOCKOO_H_ #define STOCKOO_H_ #include<string> class Stock { private: std::string company;//公司名称 long shares;//所持股票的数量 double share_val;//每股的价格 double total_val;//股票总值 void set_tot(){to

读thinking in java的收获(二) --eclipse生成javadoc文档

最开始学习java语言的时候学过生成javadoc不过当时只是用windows命令行生成.读了这里的javadoc温故而知新发现其实我们做的项目就用到了一些注释,只是没有用eclipse 生成这份文档,通过查阅,最终补全了这份知识. 一.书中的代码: <pre name="code" class="java">//:object/HelloDate.java package unit2; import java.util.Date; /** * The

C++ Primer读书笔记整理(二)

8.数组 标准库begin和end函数可作用于数组,分别用于获取指向数组首元素和尾元素下一位置的指针. 例如: int ia[] = {0, 1, 2, 3, 4}; int *beg = begin(ia); //beg指向数组首元素 int *e = end(ia); //e指向数组尾元素下一位置 begin和end函数定义在头文件iterator中. 另外:可以使用数组来初始化vector的对象: int arr[] = {0, 1, 2, 3, 4, 5}; vector<int> i

学习C++ Primer 的个人理解(二)

到了第二章,其实才算是真正的开始.也就是本书的第一部分C++基础. 第一章可以说就是第一部分的一个简单的梗概. 从第二章开始,对C++的学习步入正轨,从最基础的开始学起,也就是 变量. 而说到变量就不得不说类型. 第二章讨论的主要就是如下几点: 1.什么是基本类型,什么是复合类型? 2.什么是变量,什么是常量? 3.什么是类型别名 4.定义数据结构(struct) 我认为本章讨论常量的部分,对后面的学习影响很大,如果没有理解清楚const的复合类型的一些细节问题,会对后面函数和类的部分的学习造成

C++ primer puls 学习笔记 (二)

一.知识点回顾 1.数组(array) (1)数组的基本信息 数组是一种数据格式,能够存储多个类型的值,要声明数组,可使用声明语句,但应该包含以下三点: ● 数组名 ● 存储在每个元素中的值的类型 ● 数组中的元素数 数组声明的通用格式如下: TypeName arrayName [arraysize] arraysize必须是整形常数或const值,也可以是常量表达式(具体地说不能是变量). (2)数组编号 数组的很多用途都是用于访问单独的数组元素,C++数组从0开始编号,然后利用索引来标识访

思维启示之意外的收获(发现自己思维局限和掀开二级指针的虎皮)

潘鹏在CSDN上原创.如其它站点转载请注意排版和写明出处: 今天仍旧是最后一个离开,本来是封装的线程扩展功能来卖票的.但我想将统计是否有漏票的程序封装进去,可是一直纠结的我多个线程就有多个对象,我必需要等全部的线程执行结束才干来统计,可是我不能在接口类和线程类里来写,那我仅仅能写在对用户开放的类里,那这种话,我多个类对象谁去调???调之前我多个对象难道在main里写多次等待线程执行结束??? 由于想要解决第一个问题,我想法去封装线程的类里去接受线程回调函数里面调用的虚函数的返回值,仅仅要有返回值