刚接触c++,看着这么厚的一本c++primer,觉得无从下手,后来在cousera上找了一个课程跟着学,刚开始,觉得还是做些笔记比较好,参考《c++primer》这本书以及该课程内容完成学习总结。以前学其他的东西很后悔没有写笔记的习惯,再用到的时候有些已经忘了还要再去网上看别人的博文,所以,现在下定决心要坚持学习,坚持写笔记,哪怕只是一点点收获,加油。
学习编程还是要多练,动手编程,熟方能生巧。
首先,从把一个简单的c程序改编成一个c++程序开始。c程序以及要求是coursera课程中给出的一项作业,如下
/* Convert this program to C++
* change to C++ io
* change to one line comments
* change defines of constants to const
* change array to vector<>
* inline any short function
*/
#include <stdio.h>
#define N 40
void sum(int*p, int n, int d[])
{
int i;
*p = 0;
for (i = 0; i < n; ++i)
*p = *p + d[i];
}
int main()
{
int i;
int accum = 0;
int data[N];
for (i = 0; i < N; ++i)
data[i] = i;
sum(&accum, N, data);
printf("sum is %d\n", accum);
return 0;
}
按照要求改编以上程序:
1.将stdio.h变为iostream。
c++语言没有定义任何的输入输出语句,而是包含了一个全面的标准库,来提供IO机制。iostream库包含了两个基础类型istream和ostream,分别表示输入流和输出流。一个流就是一个字符序列,是从io设备读出或写入io设备的。“流”即stream,所表达的是,随着时间推移,字符是顺序生成或消耗的。
- istream(输入流)类型,提供输入操作
- ostream(输出流)类型,提供输出操作
- cin,一个istream对象,从标准输入读取数据
- cout,一个ostream对象,向标准输出写入数据
- cerr,一个ostream对象,通常用于输出程序错误消息,写入到标准错误(*还未使用过)
- >>运算符,用来从一个istream对象读取输入数据
- <<运算符,用来想一个ostream对象写入输出数据
- getline 函数,从一个给定的istream读取一行数据,存入一个给定的string对象中。
2.将对常量的一个宏定义改为const符号定义
- const对象一旦创建后其值就不能再改变,因此const对象必须要初始化,初始值可以是任意复杂的表达式。
- 默认状态下,const对象仅在文件内有效
//file_1.cpp定义并初始化了一个常量,该常量能被其他文件访问
extern const int bufsize = fcn();
//file_1.h头文件
extern const int bufsize;//与file_1.cpp中的bufsize是同一个
3.把 数组 改写成 标准库类型vector
- 如果要使用vector,就要包含相关的头文件,即,#include <vector>
- vector是模板而不是类型,因此首先应进行实例化。有vector生成的类型必须包含vector中元素的类型,如vector<int>
- 定义和初始化vector对象
vector<Type> v1; //v1是一个空vector,其应该存放Type类型的元素 vector<Type> v2(v1); //v2中包含有v1所有元素的副本 vector<Type> v2 = v1; //等价于上句,相当于是拷贝初始化 vector<Type> v3(n, val); //v3包含了n个重复的元素,每个元素的值都是val,直接初始化 vector<Type> v4(n); //v4包含了n个重复地执行了值初始化的对象 vector<Type> v5{a,b,c...}; //v5包含了初始值个数的元素,每个元素被赋予相应的初始值 vector<Type> v5 = {a,b,c...}; //等价于上句,拷贝初始化
- 值初始化:对于int型,元素初始值自动设为0;string,则是空string对象。、
- 通过圆括号或花括号,来区分是初始值还是元素数量
vector<int> v1(10); //v1有10个元素,每个的初始值为0 vector<int> v2{10}; //v2有1个元素,初始值为10 vector<int> v3(10,1); //v1有10个元素,每个的初始值为1 vector<int> v4{10,1}; //v2有2个元素,初始值为10、1
- vector支持的操作
v.empty() //如果v不含有任何元素,返回真;否则为假 v.size() //返回v中元素的个数 v.push_back(t) //向v的尾端添加一个值为t的元素 v[n] //返回v中第n个位置上元素的引用 v1 = v2 //用v2中元素的拷贝替换v1中的元素 v1 = {a,b,c...} //用列表中元素的拷贝替换v1中的元素 v1 == v2 //v1 和v2相等当且仅当它们元素数量相同且对应位置的元素之相同 v1 != v2 <, <=, >, >= //以字典顺序进行比较
- 不可以用下表形式添加元素,只能用push_back(t)!!!只能对确知已存在的元素位置进行下标操作!!!
4.内联函数inline
调用函数有很多有点,譬如,易读性强;保持行为的同意,每次相关操作都能保证按照同样的方式进行;若需要修改计算过程,只需一次性修改函数即可;函数可以被重复利用,省去了重新编写的工作量。但是,也有一个潜在的缺点:调用函数一般比求等价表达式的值要慢,在大多数机器上,一次函数调用包含了一系列的工作:调用前要先保存寄存器,并在返回式恢复;可能需要拷贝实参;程序转向一个新的位置继续执行 。
使用内联函数(inline)可以避免函数调用的开销。
将函数制定为内联函数(inline),通常是将它在每个调用点上“内联地”展开,假设我们把上面给定的c程序里的sum函数定义为内联函数,那么如下调用:
sum(&accum, N, data);将在编译过程中展开成类似于如下形式:
int i;
*p = 0;
for (i = 0; i < n; ++i)
*p = *p + d[i];
从而消除了调用函数的开销,在sum函数的返回类型前面加上关键字 inline,就可以将其声明成内联函数了。
一般,内联机制适用于优化规模较小、流程直接、频繁调用的函数。
通过以上几个方面,按照题目要求将上述c程序改为c++程序,我的结果是:
/*This is my first assignment.
A c++ program converted from c.
*/
#include <iostream>
#include <vector>
using namespace std;
inline void sum(int* p, int n, vector<int> d)
{
int i;
*p = 0;
for (i = 0; i < n; ++i)
*p = *p + d[i];
}
int main()
{
int i;
int accum = 0;
const int N = 40;
vector<int> data(N);
for (i = 0; i < N; ++i)
data[i] = i;
sum(&accum, N, data);
cout << "sum is " << accum << endl;
return 0;
}
第一个小任务至此完成,学习了输入输出流、const、vector类以及inline内联函数的用法。
######以上各知识点均参考《c++ Primer》进行学习与记录。#####