刚接触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 40void 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符号定义
#define N 40=> const int N=40const对象一旦创建后其值就不能再改变,因此const对象必须要初始化,初始值可以是任意复杂的表达式。 例: const int i = get_size(); //正确,运行时初始化 const int j = 66; // 正确,编译时初始化 const int k; // 错误,没有初始化默认状态下,const对象仅在文件内有效 如果程序内包含多个文件,那么每个用了const对象的文件都必须得能访问到它的初始值。为做到这一点,须在每一个用到变量的文件中个都有对它的定义。为支持这一用法,同时避免对同一变量的重复定义,默认情况下,const对象被设定为仅在文件内有效。当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。 有些时候有这样一种const变量,它的初始值不是一个变量表达式,但是需要在文件间共享,这种情况下,我们不希望编译器为每个文件分别生成独立的变量。相反,我们想让这类const对象像其他对象一样工作,也就是说,只在一个文件中定义const,而在其他多个文件中声明并且使用它。 解决方法是:对于const变量不管是声明还是定义都添加 extern 关键字,这样只需定义一次即可://file_1.cpp定义并初始化了一个常量,该常量能被其他文件访问extern const int bufsize = fcn();//file_1.h头文件extern const int bufsize;//与file_1.cpp中的bufsize是同一个3.把 数组 改写成 标准库类型vector
标准库类型vector表示对象的集合,其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引,索引用于访问对象。因为vector“容纳着”其他对象,所以它也常被称作容器。c++语言既有类模板,也有函数模板,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个元素,每个的初始值为0vector<int> v2{10}; //v2有1个元素,初始值为10vector<int> v3(10,1); //v1有10个元素,每个的初始值为1vector<int> v4{10,1}; //v2有2个元素,初始值为10、1vector支持的操作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》进行学习与记录。#####
新闻热点
疑难解答
图片精选