小言_互联网的博客

C++PrimerPlus:前言 + 第一章:开始(笔记+源代码)

358人阅读  评论(0)

说明

C++PrimerPlus系列博客是对于书中的知识点进行总结和简短提炼。
建议读者参考C++博客同时阅读,内容互补。

前言

C++本身在不断成熟,语言本身和程序社区的关注点机器效率——>编程效率。

新标准的目标:
语言更统一,更易教学。
标准库更安全简单、安全、使用更高效。
编写高效率的抽象和库变得更简单。

C++语言的组成:
低级语言:大部分继承自C语言。
现代高级语言:自定义类型以及组织大规模程序和系统。(面向对象设计)
标准库:利用高级特性提供有用的数据结构和算法。(STL)

注意:在实际编码的过程中,更多的去考虑使用标准库

标准库的优势:
更加容易实现。
更加容易理解。
出错更少。
标准库能满足大多数开发应用场景。
标准库提供的数据结构和算法效率更高。

第一章:开始

学习一门新的程序设计语言的最好方法就是练习编写程序。

只有不断编码的的过程中才会验证自己有没有掌握,才能发现自己的问题并解决问题从而更快的提高。

1.1编写一个简单的C++程序

每个C++程序都包含一个或者多个函数,其中一个必须命名为main。
操作系统通过调用main来运行C++程序。

int main()
{
   
return 0;
}

一个函数的定义包括四个部分:
返回类型
函数名
一个括号包围的形参列表。
函数体。(以左花括号开始,以右花括号结束的语句块)

{
   
       return 0;
}

虽然main函数在某种程度上比较特殊,但是其定义与其他函数一样,也是上面4个部分。

当return语句包括一个值时,此返回值的类型必须与函数的返回类型相容。

大多数系统中:main函数返回值被用来指示状态:
返回值0:表明成功。
返回值非0:含义由系统定义,通常用来指出错误类型。

类型决定数据元素的内容,也决定这类数据可以进行的计算。

思考:补码的设计思路和规范,char类型一个字节8位可以表示2^8= 256个数字,那么为什么表示的是[-128,127]呢?
原因就是内存中去表示char类型数的时候不仅仅只是保存数据,而且还要考虑数据保存之后的计算。
关于补码的设计规则我在C语言博客中已经详细说明,内存模型和计算机编码规则将持续在我们整个计算机的学习之中。所以建议读者进行跳转阅读:

→点击此处跳转到计算机编码规则和补码的设计博客

1.2初识输入输出

Iostream库中包含两个基本类型:
Istream:输入流,从IO设备读出。
ostream:输出流,写入IO设备。

流:字符序列。

标准库定义了4个IO对象:
cin:istream类型对象:标准输入,用来从标准输入读取数据。
cout:ostream类型对象:标准输出,用于将数据写入标准输出。标准输出(standard output)输出流,通常与程序执行所在窗口相关联。
cerr:ostream类型对象:标准错误。(输出警告和错误消息)关联到标准错误,,通常写入到与标准输出相同的设备。默认情况下,写到cerr的数据是不缓冲的。cerr通常用于输出错误信息或其他不属于程序正常逻辑的输出内容。
clog:ostream类型对象:输出程序运行时的一般性信息,关联到标准错误。默认情况下,写到clog的数据是被缓冲的。clog通常用于报告程序的执行信息,存入一个日志文件中。

一个使用IO库的程序:

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
   
	cout << "Enter two numbers:" << endl;
	int v1 = 0;
	int v2 = 0;
	cin >> v1 >> v2;
	cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << endl;
	cout << "hello world" << endl;
	cout << "The sum of " << v1 << " and " << v2 << " is " << v1 * v2 << endl;
	return 0;
}

运行结果:

一般将一个程序的所有#include指令都放在源文件的开始位置。

输出运算符<<:
左侧运算对象:必须是一个ostream对象。
右侧运算对象:要打印的值。
运算结果:将给定的值写到给定的ostream对象中。

上面代码中出现的endl:
操纵符。
效果:结束当前行,将与设备关联的缓冲区中的内容刷新到设备中。
刷新缓冲区:程序所产生的输出都真正写入输出流中,而不是停留在内存缓冲区等待写入。

注意:
调试程序的时候添加打印语句,应该保证语句”一直”刷新缓冲区。
否则如果程序崩溃,输出可能停留在缓冲区没有刷新从而导致程序崩溃位置错误推断。

命名空间:
避免不经意的名字定义冲突。
避免使用库中相同名字而导致冲突。

标准库定义的所有名字都在命名空间std中。

初始化变量:创建一个变量的同时为它赋一个值。

未初始化的变量:未赋予初值的变量。
类类型的变量如果未指定初值,则按类定义指定的方式进行初始化。
定义在函数内部的内置类型变量默认是不初始化的,除非有显式的初始化语句。

试图使用一个未初始化变量的值是错误的。未初始化变量是bug的常见成因。

1.3注释简介

注释的作用:
帮助读者理解程序。
概述算法。
确定变量的用途。
解释难懂的代码段。

编译器会忽略注释,因此注释对程序的行为或性能不会有任何影响。

错误的注释比完全没有注释更糟糕,因为它会误导读者。所以在修改代码的时候,同时要更新注释。

→点击此处跳转到注释的种类和详细说明博客

注释代码:

#include <iostream>
using namespace std;
/*
*简单主函数
*读取两个数,求它们的和
*/
int main(int argc, char *argv[])
{
   
	cout << "Enter two numbers:" << endl;//提示用户输入两个数
	int v1 = 0;//保存我们读入的输入数据变量
	int v2 = 0;//保存我们读入的输入数据变量
	cin >> v1 >> v2;//读取输入数据
	cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << endl;
	cout << "hello world" << endl;
	cout << "The sum of " << v1 << " and " << v2 << " is " << v1 * v2 << endl;
	return 0;
}

运行结果:

1.4控制流

→点击此处跳转到程序设计流程——循环详细说明博客

while循环:

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
   
	int sum = 0;
	int val = 1;
	while (val <= 10)//只要val的值小于10,while循环就会持续执行
	{
   
		sum += val;//将sum+val的值赋值给sum
		++val;//将val+1
	}
	cout << "Sum of 1 to 10 inclusive is " << sum << endl;
	return 0;
}

运行结果:

for循环:

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
   
	int sum = 0;
	//从1加到10
	for (int val = 0; val <= 10; ++val)
	{
   
		sum += val;//等价于sum = sum + val
	}
	cout << "Sum of 1 to 10 inclusive is " << sum << endl;
	return 0;
}

运行结果:

读取数量不定的输入数据:

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
   
	int sum = 0;
	int val = 0;
	//读取数据直到遇到文件尾,计算所有读入的值的和
	while (cin>>val)
	{
   
		sum += val;//等价于sum = sum + val
	}
	cout << "Sum is " << sum << endl;
	return 0;
}

运行结果:

如果使用istream对象作为条件,就是检测流的状态:
条件为真:流是有效的,流未遇到错误,检测成功。
条件为假:遇到文件结束符(end of file)或者遇到无效输入时。对象状态编程无效为假。

从键盘输入文件结束符:
Windows: Ctrl+Z(按住Ctrl键的同时按Z键),然后按Enter或Return键。
UNIX/Mac OS X: Ctrl+D。

编译器能够检查出来程序的错误:
语法错误。
类型错误。
声明错误。

C++程序中的每个名字都要先声明后使用。
两种常见的声明错误是:

对来自标准库的名字忘记使用std::。
标识符名字拼写错误:。

关于编码风格的思考:
当你要选择一种格式风格时,思考一下它会对程序的可读性和易理解性有什么影响,而一旦选择了一种风格,就要坚持使用。

1.5类

在C++中,我们通过定义一个类(class)来定义自己的数据结构。
类机制是C++最重要的特性之一。

一个类定义了一个类型,以及与其关联的一组操作。

类的作者决定了类类型对象上可以使用的所有操作。
为了使用一个类,我们不必关心它是如何实现的,只需知道类对象可以执行什么操作。

对于不属于标准库的头文件,则用双引号(" ")包围。

文件重定向

在默认情况下我们的输入流是键盘设备,输出流是显示器设备。
我们可以通过文件重定向来修改输入流的源文件和输出到的文件。
例如:
我们上面使用过的代码:输入流是键盘设备,输出流是显示器。

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
   
	cout << "Enter two numbers:" << endl;
	int v1 = 0;
	int v2 = 0;
	cin >> v1 >> v2;
	cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << endl;
	cout << "hello world" << endl;
	cout << "The sum of " << v1 << " and " << v2 << " is " << v1 * v2 << endl;
	return 0;
}

运行结果:

接下来我们演示重定向输入输出文件。

如果使用文件重定向,我们可以选择某一个文件的内容作为程序的输入,选择某一个文件作为保存程序的输出结果。
在VS2013中操作如下:项目→属性→配置属性→调试→命令参数,输出以下参数。

在源代码所文件中创建input.txt文件和out.txt文件:

在input文件中输入22 33:

<input.txt>表示项目工程根目录下,有一个input.txt的文本文件,就是程序的输入。
<out.txt>表示项目工程根目录下,有一个out.txt的文本文件,把程序的输入保存到这个文件里面。

再次运行程序,不用输入数据,也不用输出,程序就结束了。

这时候,再去看看out.txt文件:


网站http://www.informit.com/title/0321714113上,第1章的代码目录中包含了头文件Sales_item.h。将它拷贝到你自己的工作目录中,编写下面代码。

成员函数的使用&Sales_ite对象的加法:

#include <iostream>
#include "Sales_item.h"
using namespace std;

int main(int argc, char *argv[])
{
   
	Sales_item item1;
	Sales_item item2;
	cin >> item1 >> item2;
	//首先检查item1 和 item2 是否表示相同的书
	if (item1.isbn() == item2.isbn())
	{
   
		cout << item1 + item2 << endl;
		return 0;//表示成功
	}
	else
	{
   
		cerr << "Data must refer to same ISBN" << endl;
		return -1;//表示失败
	}
	return 0;
}

运行结果:

类的组成:
数据成员。
函数成员(方法)。

我们通常以一个类对象的名义来调用成员函数:

cin.size();

使用点运算符(.)来表达我们需要调用“名为cin的对象的size函数成员”。

点运算符只能用于类类型的对象:
左侧运算对象必须是一个类类型的对象。
右侧运算对象必须是该类型的一个成员名。
运算结果为右侧运算对象指定的成员。

1.6书店程序

#include <iostream>
#include "Sales_item.h"

using namespace std;

int main(int argc, char *argv[])
{
   
	Sales_item total;//保存下一条交易记录的变量
	//记录第一条交易记录并且确保有数据可以处理
	if (cin >> total)
	{
   
		Sales_item trans;//保存和的变量
		//读入并处理剩余交易记录
		while (cin>>trans)
		{
   
			if (total.isbn() == trans.isbn())
			{
   
				total += trans;//更新销售额
			}
			else
			{
   
				//打印前一本书的结果
				cout << total << endl;
				total = trans;//total表示下一本书的销售额
			}
		}
		cout << total << endl;//打印最后一本书的结果
	}
	else
	{
   
		//没有输入,警告读者
		cerr << "No data?!" << endl;
		return -1;//表示失败
	}
	return 0;
}

缓冲区说明:
一个存储区域,用于保存数据。
IO设施通常将输入(或输出)数据保存在一个缓冲区中,读写缓冲区的动作与程序中的动作是无关的。我们可以显式地刷新输出缓冲,以便强制将缓冲区中的数据写入输出设备。默认情况下,读cin会刷新cout;程序非正常终止时也会刷新cout。


转载:https://blog.csdn.net/qq_43648751/article/details/116139408
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场