把"Essential C++"读薄(一)
来源:互联网 发布:apache服务器下载64位 编辑:程序博客网 时间:2024/05/22 07:08
一、Basic C++ Programming
1. 变量初始化的两种方式
· assignment运算符(=)初始化:沿袭自C语言,如果对象属于内置类型或者可以单一值初始化,这就没问题。例:string sequence_name = “Fibonacci”;
· constructor initialization syntax 构造函数初始化语法:在对象需要多个初值的情况,如complex类。例:complex<double> purei(0, 7);
2. array和vector
//用已初始化的array作为vector的初值const int seq_size = 18;int elem_vals[seq_size] = { 1, 2, 3, 3, 4, 7, 2, 5, 12 3, 6, 10, 4, 9, 16, 5, 12, 22};vector<int> elem_seq(elem_vals, elem_vals + seq_size);
3. 指针的使用
一个没有指向任何对象的指针,地址为0(null指针),在使用指针前,必须在提领之前确定它的确指向某对象。为了防止对null指针进行提领,可以事先检验地址是否是0。if( pi && … )
4. rand()和srand()
#include <cstdlib>const int seq_cnt = 6;srand(seq_cnt);seq_index = rand() % seq_cnt;
rand()和srand()都是标准库提供的伪随机数生成器,srand()的参数是所谓随机数生成器种子(seed),每次调用rand(),都会返回一个0和seq_cnt之间的一个整数,这里的值被限制在0~5。
5. 文件的读写
#include <fstream>//以输出模式开启seq_data.txt//如果指定文件不存在,会有一个文件被产生并打开供输出使用//如果文件已存在,这个文件被打开用于输出,而原有的数据会被丢弃ofstream outfile("seq_data.txt");//不希望丢弃原有内容,可增加一个参数,以append model打开文件//ofstream outfile("seq_data.txt", ios_base::app);if(!outfile) cerr << "Oops! Unable to save session data!\n";else //将数据写入 outfile << usr_name << ' ' << num_tires << ' ' << nun_right << endl;//以读取模式(input mode)打开infileistream infile("seq_data.txt");if(!infile) {...}else{ string name; int nt, nc; //这条与语句的返回值就是从infile中读到的class object //读到文件末尾返回false while(infile >> name) { //文件的形式:anna 24 19 //分别把两个整数读到nt和nc中 infile >> nt > nc; if(name == usr_name) {...} }}//同时读写同一个文件,为了以追加模式打开,传入第二参数fstream iofile("seq_data.txt", ios_base::in|ios_base::app);if(!iofile) {...}else //开始读取之前,将文件重新定义至起始处 iofile.seekg(0); //其他部分和上面的读取相同
当我们以追加模式来打开文档,文件位置会位于末尾。如果我们没有先重新定位,就试着读取文件内容,那么立刻就会遇上“文件结束”的状况。seekg()可将iofile重新定位至文件的起始处。由于此文件是以追加模式开启,因此任何写入操作都会将数据添加在文件末尾。
二、 Procedural Programming
1. pass by value && pass by reference
调用函数时,会在内存中建立一块特殊区域,就是程序堆栈(program stack),这个特殊区域提供了每个参数的存储空间,用pass by value的方式,使得对象在堆栈中复制了一份副本,对堆栈中的副本(形参)操作,一旦函数完成,这块堆栈内存就被释放掉,真正的自己(实参)没有发生任何改变。为了让形参和实参产生关联,要通过pass by reference的方式。
以pass by reference方式将对象作为函数参数传入时,对象本身并不会复制出另一份,复制的是对象的地址。函数对该对象的任何操作,都相当于是对传入的对象进行间接操作。用pass by reference的方式传参,还可以降低复制大型对象的额外负担。
但是注意下面情况,对根本不存在的对象进行寻址操作,是很不好的习惯。
vector<int> fibon_seq(int size){ vector<int> elems(size); for(int ix = 0; ix < size; ++ix) if(ix == 0 || ix == 1) elems[ix] == 1; else elems[ix] = elems[ix - 1] + elems[ix - 2]; return elems}
这里以pointer或reference形式将elems返回,都不正确,因为elems在fibon_seq()执行完毕已不存在。如果将elems以传值方式返回,则不会产生问题,因为返回的是对象副本,它在函数之外仍然存在。如果返回的对象函数内的局部变量,就不能用传址的方式返回。除非我们用局部静态对象定义elems,如下:
vector<int>* fibon_seq(int size){ static vector<int> elems; ... return &elems;}
局部静态对象所处的内存空间,即使在不同的函数调用过程中,依然持续存在,elems的内容不再当fibon_seq()每次被调用时就破坏又被重新建立。现在可以将elems的地址安全返回。
2. 动态内存管理
int *pia = new int[24];delete[] pia;
3. function overloading
函数重载机制,参数列表不相同(可能是参数类型不同,可能是参数个数不同)的两个或多个函数,可以拥有相同的函数名称。注意编译器无法根据函数返回类型来区分两个具有相同名称的函数。
4. function template
template<typename T>void display_message(const string &msg, const vector<T> &vec){ cout << msg; for(int ix = 0; ix < vec.size(); ++ix) { T t = vec[ix]; cout << t << ' '; }}int main(){ vector<int> ivec;//编译器将T绑定为int类型 string msg; display_message(msg, ivec); vector<string> svec;//编译器将T绑定为string类型 //... display_message(msg, svec);}
一般而言,如果函数具备多种实现方式,我们可将它重载,其每份实例提供的是相同的通用服务。如果我们希望程序代码的主体不变,仅仅改变其中用到的数据类型,可以通果function template达到目的。
- 把"Essential C++"读薄(一)
- 《Essential C++》读书笔记(一)
- 《Essential C++》随笔一
- Essential COM笔记(一)
- 《Essential C++》笔记一、C++编程基础
- 《Essential C++》读书笔记(二)
- 《Essential C++》读书笔记(三)
- 《Essential C++》读书笔记(四)
- 《Essential C++》读书笔记(五)
- 《Essential C++》读书笔记(六)
- 《Essential C++》读书笔记(七)
- 《Essential C++》读书笔记(八)
- Essential C++学习笔记(一)
- data model essential 之读书笔记(一)
- Essential Qt 第四章 记事本(一)
- Essential C++ 笔记 (一)
- 快速阅读《Essential C++》
- Essential C++
- vue(1) -- this.$nextTick
- Matlab 相关函数说明
- 当我真正搞懂主席树!!!
- 电路交换和分组交换
- 剑指offer 面试题42 翻转单词顺序 VS 左旋转字符串
- 把"Essential C++"读薄(一)
- 配置ButterKnife所踩的坑
- android网络编程之HttpUrlConnection--POST请求
- Latex:基本用法、表格、公式、算法(持续更新)
- 2017年第0届浙江工业大学之江学院程序设计竞赛决赛—K qwb与小数
- 常用工具类
- 【实训】第一周总结下
- linux驱动开发 --miscdevice
- 用nc做网络压力测试