【Essential C++学习笔记】 第一章 C++编程基础

第一章 C++编程基础

1.1 如何撰写C++程序

1.命名空间之 using nanespace std;

​ using和 namespace都是C关键词。std 是标准程序库所驻之命名空间(namespace〉的名称。标准程序库所提供的任何事物(诸如 string class 以及cout, cin这两个iostream类对象)都被封装在命名空间std内.当然啦,所谓命名空间( namespace)是一种将程序库名称封装起来的方法。通过这种方法,可以避免和应用程序发生命名冲突的问题(所谓命名冲突是指在应用程序内两个不同的实体(entity)具有相同名称,导致程序无法区分两者。命名冲突发生时,程序必须等到该命名冲突获得决议〔 resolved)之后,才得以继续执行)·

1.2.对象的定义与初始化

1.构造函数语法(constructor syntax )

​ 为什么需要两种不同的初始化语法呢?“以运算符(=)进行初始化”这个操作系衍袭C语言而来。如果对象属于内建型别,或者对象可以单一值加以初始化,但是如果对象需要多个初始值,这种方式就没办法完成任务了.以标准程序库中的复数(complexnumber)类为例,它就需要两个初始值,一为实部,一为虚部。

1.4 条件(Conditaional〉语句和循环( Loop〉语句

1. if

	if (usr_guess == next_elem)
	{}
	else
    {}

	if (num_tries == 1)
		cout << "Do Something";
	if (num_tries == 2)
		cout << "Do Something";
	if (num_tries == 3)
		cout << "Do Something";

2.switch

每个case标签表达式值都会依次和switch表达式值相比较,不吻合着便依次跳过.当某个casc标签之表达式值吻合时,便开始执行该case标签之后的语句——这个执行动作会一直贯彻到swit.tc:语句的最底端.如果我们没有加.上 break语句、每项都会对比

	switch (num_tries) {
		case 1:
			cout << "Do Something";
			break;
		case 2:
			cout << "Do Something";
			break;
		case 3:
			cout << "Do Something";
			break;
		default:
			cout << "default";
	}

3.while

	while (next_seq == true) {
		cout << "是否继续?";
        // break: 主动结束循环
        // continue: 中止当前循环,跳至下一次循环
	}

4.for

	for (int i = 1; i < 10; i++) {
		cout << i;
	}

1.5如何运用Arrays(数组)和Vectors (向量)

1.Arrays(数组)

要定义array,我们必须指定array 的元素型别,还得给予array·个名称,并指定其尺度大小一—亦即 array所能储存的元素个数.array 的尺度必须是个常曩表达式,

1. 未赋初值
	int pell_arrays[18];
	pell_arrays[0] = 10;
	cout << pell_arrays[0];
2.赋初值
    int elem_seq[3] = {
		1, 2, 3
	};
	cout << elem_seq[2];

2.Vectors (向量)

#include 	 // 需要引入vector头文件
1. 未赋初值
	vectorpell_seq(18);
	pell_seq[0] = 10;
	cout << pell_seq[0];
2. 赋初值
    int elem_vals[3] = {
		1, 2, 3
	};
	//传入的两个值其实都是实际内存位置
	vectorpell_seq(elem_vals, elem_vals + 3);
	cout << pell_seq[0];
	cout << pell_seq[1];
	cout << pell_seq[2];
3.迭代遍历
    for (int i = 0; i < pell_seq.size(); ++i) {
		cout << pell_seq[i] << " ";
	}

1.6 指针带来弹性

1.指针特效

指针:某特定的内存地址,在我们的程序中,它可以增加程序本身的弹性,但同时也增加了直接操控对象时所没有的复杂度.

取址符(&):获取对象所在的内存地址

提领(*):存取一个由指针寻址的对象,也就是取得“位于该指针之内的内存地址上”的对象 ,在指针之前使用“ * ”可达到该目的

	int ival = 1024;
	int *pi = &ival; // 一个int型对象的指针
	cout << "地址:" << pi << ",对象:" << *pi;

空指针:一个为指向任何对象的指针,内含地址为0,此时不能提领操作

	int *pi = 0;
	if (pi && *pi != 1024)
		cout << "地址:" << pi << ",对象:" << *pi;
	else
		*pi = 1024;
	cout << "地址1:" << pi << ",对象:" << *pi;

C++函数参数中&和*的意义
https://blog.csdn.net/qq_34201858/article/details/104161539

2.指针与vector的应用

(1) 常规初始化

	vector a, b, c, d, e, f; //初始化6个vector对象
	vector *pv = 0; //初始化一个指向vector的空指针
    pv = &a; //明确的将数列的内存地址赋值给指针

(2)直接将每个数列的地址存入vector指针数组中

	vector a, b, c, d, e, f; //初始化6个vector对象
	vector *seq_addrs[6] = {
		&a, &b, &c, &d, &e, &f,
	};

	vector *pv = 0; //初始化一个指向vector的空指针
	for (int i = 1; i < 6; ++i) {
		pv = seq_addrs[i];
		// Do Something
	}
}

(3) 指针的使用

// 欲检查vector b的第一个元素是否为1,一般会这样写
	b.push_back(1); // vector 添加元素,这些元素是加到数值尾部的
	b.push_back(2);
	if (!b.empty() && b[1] == 1) {
		cout << "PASS";
	} else {
		cout << "FAIL";
	}
// 如何通过pv指针来控制对象进行操作呢 (-> == .)
  	vector *pv = &b; //初始化一个指向vector的空指针
	if (pv && !pv -> empty() && ((*pv)[1] == 2)) {
		cout << "PASS";
	} else {
		cout << "FAIL";
	}

3.随机rand() 和srand()

#include  // 需要引入头文件
#include 

srand(time(0));	//不设置每次结果都一致
int seq_index = rand() % 6; // 随机范围: k = rand() % (max + 1 - min) + min;
pv = seq_addrs[seq_index];

1.7文件的读写

#include  // 需要引入头文件

1. 输出文件的声明 ofstream outfile(“xxx”)

声明outfile 的同时,会发生什么事呢?如果指定的文件并不存在,便会有一个文件被产生出来并开启作为输出之用。如果指定的文件已经存在、这个文件会被开启作为输出之用,而文件中原已存在的数据会被丢弃.如果文件已经存在,而我们并不希望丢弃其原有内容,而是希望增加新数据到文件中,那么我们必须以追加模式( append mode)开启这个文件.为此,我们提供第二个参数ios_base : :app传给ost ream对象。ofstream outfile(“seq_data.txt”);

ofstream outfile("seq_data.txt"); // 以输出模式开启文件,对象名为 outfile
ofstream outfile("seq_data.txt", ios_base::app); // 以追加模式开启文件,新数据会被加到文件尾端

2.输出文件的使用

文件有可能开启失败。在进行写人操作之前,我们必须确定文件的确开启成功最简单的方法便是检验class object的真伪:

如果文件未能成功开启,ofstream对象会被计算为false。
本例中我们将信息写入cerz,告知用户这个状况.cerr 代表标准错误输出设备,
和cout 一样,cerr将其输出结果导至用户的终端机。
两者的唯一差别是,cerr的输出结果并无缓冲—它会立即显示于用户终端机上.

	string usr_name = "majin";
	int num_tries = 1966;
	int num_right = 8;
	ofstream outfile("seq_data.txt", ios_base::app);
	if (!outfile)
		cerr << "Fail!\n";
	else
		outfile << usr_name << " "
		        << num_tries << " "
		        << num_right << " " << endl;

3.读取文件的声明和使用 ifstream infile(“seq_data.txt”);

如果要开启–个可供读取的文件,我们可定义一个ifstream 对象,并将文件名传入。如果文件未能开启成功,itstrearn对象会被核定为false,如果成功,该文件的写入位置会被设定在起始处.

	string usr_name = "majin";
	int num_tries = 0;
	int num_right = 0;

	ifstream infile("seq_data.txt");
	if (!infile) {
		cerr << "Fail!\n";
	} else {
		// ok:读取文件中的每一行
		// 检查这个用户是否曾经玩过这个程序
		// nt:猜过的总次数(nun_tries)
		// nc:猜对的总次数(nun_correct)
		string name;
		int nt;
		int nc;

		while (infile >> name) {
			infile >> nt >> nc;
			if (name == usr_name) {
				cout << "欢迎你," << usr_name
				     << "\n你当前的成绩是:" << nc
				     << "猜对的次数:" << nt << "\n祝你好运";
				num_tries = nt;
				num_right = nc;
			}
		}
	}

4.同时读写文件

如果想要同时读写同一个文件,我们得定义一个fstream 对象。为了以追加模式( append mode)开启,我们得传入第二参数值 ios_base::in | ios_base::app

	string usr_name = "majin";
	int num_tries = 0;
	int num_right = 0;

	fstream iofile("seq_data.txt", ios_base::in | ios_base::app);
	if (! iofile) {
		cerr << "Fail!\n";
	} else {
		iofile.seekg(0);// /开始读取之前,将文件重新定位至起始处
		string name;
		int nt;
		int nc;
		while (iofile >> name) {
			iofile >> nt >> nc;
			if (name == usr_name) {
				cout << "欢迎你," << usr_name
				     << "\n你当前的成绩是:" << nc
				     << "猜对的次数:" << nt << "\n祝你好运";
				num_tries = nt;
				num_right = nc;
			}
		}
	}

当我们以附加模式来开启文件时,文件位置会位于尾端。如果我们没有先重新定位,就试着读取文件内容,那么立刻就会遇上“读到文件尾”的状况. **seekg ()**可将文件位置重新定位至文件的起始处。由于此文件是以追加模式开启,因此,任何写入操作都会将数据附加于文件最末端。

Ex1.5 C style string(C风格字符串)

1.定义(cstring)

C程序把指向以空字符结束的字符数组的指针视为字符串。
在C++中,字符串字面值就是C风格字符串。C标准库定义一系列处理这种字符串的库函数,C++中将这些标准库函数放在cstring头文件中。由于C风格字符串本质上容易出错,C++程序应该优先使用C++标准库类string而少使用C风格字符串。C++标准库类string比C风格字符串更安全,效率更高。网络程序中大量的安全漏洞都源于与使用C风格字符串和数组相关的缺陷。

C风格字符串即不能确切地归结为C语言的类型,也不能归结为C++语言类型,而是以空字符null结束的字符串数组。

2.C风格字符串的使用

C++语言通过(const)char*类型的指针来操作C风格字符串。

#include
using namespace std;
 
int main()
{
	char pp[]={'z','h'};
	const char *cp=pp;
    while(*cp)
	{
		cout<<*cp<

3.尽量使用C++标准库string 而不是使用C风格字符串

Ex1.6 标准输入流对象 Cin

1.输入原理:

  • 程序的输入都建有一个缓冲区,即输入缓冲区。
  • 一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据。
  • 正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入

2.cin>>

该操作符是根据后面变量的类型读取数据。

输入结束条件 :遇到Enter、Space、Tab键。

当cin>>从缓冲区中读取数据时,若缓冲区中第一个字符是空格、tab或换行这些分隔符时,cin>>会将其忽略并清除,继续读取下一个字符

若缓冲区为空,则继续等待。但是如果读取成功,字符后面的分隔符是残留在缓冲区的,cin>>不做处理。

在这里有点需要说明:当我们从键盘输入字符串的时候需要敲一下回车键才能够将这个字符串送入到缓冲区中,那么敲入的这个回车键(\r)会被转换为一个换行符\n,这个换行符\n也会被存储在缓冲区中并且被当成一个字符来计算!比如我们在键盘上敲下了123456这个字符串,然后敲一下回车键(\r)将这个字符串送入了缓冲区中,那么此时缓冲区中的字节个数是7 ,而不是6。

你可能感兴趣的:(C++学习,c++,学习)