剛接觸c++,看著這么厚的一本c++PRimer,覺得無從下手,后來在cousera上找了一個(gè)課程跟著學(xué),剛開始,覺得還是做些筆記比較好,參考《c++primer》這本書以及該課程內(nèi)容完成學(xué)習(xí)總結(jié)。以前學(xué)其他的東西很后悔沒有寫筆記的習(xí)慣,再用到的時(shí)候有些已經(jīng)忘了還要再去網(wǎng)上看別人的博文,所以,現(xiàn)在下定決心要堅(jiān)持學(xué)習(xí),堅(jiān)持寫筆記,哪怕只是一點(diǎn)點(diǎn)收獲,加油。
學(xué)習(xí)編程還是要多練,動(dòng)手編程,熟方能生巧。
首先,從把一個(gè)簡(jiǎn)單的c程序改編成一個(gè)c++程序開始。c程序以及要求是coursera課程中給出的一項(xiàng)作業(yè),如下
/* 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變?yōu)閕ostream。
c++語言沒有定義任何的輸入輸出語句,而是包含了一個(gè)全面的標(biāo)準(zhǔn)庫,來提供IO機(jī)制。iostream庫包含了兩個(gè)基礎(chǔ)類型istream和ostream,分別表示輸入流和輸出流。一個(gè)流就是一個(gè)字符序列,是從io設(shè)備讀出或?qū)懭雐o設(shè)備的?!傲鳌奔磗tream,所表達(dá)的是,隨著時(shí)間推移,字符是順序生成或消耗的。
istream(輸入流)類型,提供輸入操作 ostream(輸出流)類型,提供輸出操作 cin,一個(gè)istream對(duì)象,從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù) cout,一個(gè)ostream對(duì)象,向標(biāo)準(zhǔn)輸出寫入數(shù)據(jù) cerr,一個(gè)ostream對(duì)象,通常用于輸出程序錯(cuò)誤消息,寫入到標(biāo)準(zhǔn)錯(cuò)誤(*還未使用過) >>運(yùn)算符,用來從一個(gè)istream對(duì)象讀取輸入數(shù)據(jù) <<運(yùn)算符,用來想一個(gè)ostream對(duì)象寫入輸出數(shù)據(jù) getline 函數(shù),從一個(gè)給定的istream讀取一行數(shù)據(jù),存入一個(gè)給定的string對(duì)象中。2.將對(duì)常量的一個(gè)宏定義改為const符號(hào)定義
#define N 40=> const int N=40const對(duì)象一旦創(chuàng)建后其值就不能再改變,因此const對(duì)象必須要初始化,初始值可以是任意復(fù)雜的表達(dá)式。 例: const int i = get_size(); //正確,運(yùn)行時(shí)初始化 const int j = 66; // 正確,編譯時(shí)初始化 const int k; // 錯(cuò)誤,沒有初始化默認(rèn)狀態(tài)下,const對(duì)象僅在文件內(nèi)有效 如果程序內(nèi)包含多個(gè)文件,那么每個(gè)用了const對(duì)象的文件都必須得能訪問到它的初始值。為做到這一點(diǎn),須在每一個(gè)用到變量的文件中個(gè)都有對(duì)它的定義。為支持這一用法,同時(shí)避免對(duì)同一變量的重復(fù)定義,默認(rèn)情況下,const對(duì)象被設(shè)定為僅在文件內(nèi)有效。當(dāng)多個(gè)文件中出現(xiàn)了同名的const變量時(shí),其實(shí)等同于在不同文件中分別定義了獨(dú)立的變量。 有些時(shí)候有這樣一種const變量,它的初始值不是一個(gè)變量表達(dá)式,但是需要在文件間共享,這種情況下,我們不希望編譯器為每個(gè)文件分別生成獨(dú)立的變量。相反,我們想讓這類const對(duì)象像其他對(duì)象一樣工作,也就是說,只在一個(gè)文件中定義const,而在其他多個(gè)文件中聲明并且使用它。 解決方法是:對(duì)于const變量不管是聲明還是定義都添加 extern 關(guān)鍵字,這樣只需定義一次即可: //file_1.cpp定義并初始化了一個(gè)常量,該常量能被其他文件訪問extern const int bufsize = fcn();//file_1.h頭文件extern const int bufsize;//與file_1.cpp中的bufsize是同一個(gè)3.把 數(shù)組 改寫成 標(biāo)準(zhǔn)庫類型vector
標(biāo)準(zhǔn)庫類型vector表示對(duì)象的集合,其中所有對(duì)象的類型都相同。集合中的每個(gè)對(duì)象都有一個(gè)與之對(duì)應(yīng)的索引,索引用于訪問對(duì)象。因?yàn)関ector“容納著”其他對(duì)象,所以它也常被稱作容器。c++語言既有類模板,也有函數(shù)模板,vector是一個(gè)類模板。 如果要使用vector,就要包含相關(guān)的頭文件,即,#include <vector>vector是模板而不是類型,因此首先應(yīng)進(jìn)行實(shí)例化。有vector生成的類型必須包含vector中元素的類型,如vector<int>定義和初始化vector對(duì)象vector<Type> v1; //v1是一個(gè)空vector,其應(yīng)該存放Type類型的元素vector<Type> v2(v1); //v2中包含有v1所有元素的副本vector<Type> v2 = v1; //等價(jià)于上句,相當(dāng)于是拷貝初始化vector<Type> v3(n, val); //v3包含了n個(gè)重復(fù)的元素,每個(gè)元素的值都是val,直接初始化vector<Type> v4(n); //v4包含了n個(gè)重復(fù)地執(zhí)行了值初始化的對(duì)象vector<Type> v5{a,b,c...}; //v5包含了初始值個(gè)數(shù)的元素,每個(gè)元素被賦予相應(yīng)的初始值vector<Type> v5 = {a,b,c...}; //等價(jià)于上句,拷貝初始化值初始化:對(duì)于int型,元素初始值自動(dòng)設(shè)為0;string,則是空string對(duì)象。、通過圓括號(hào)或花括號(hào),來區(qū)分是初始值還是元素?cái)?shù)量vector<int> v1(10); //v1有10個(gè)元素,每個(gè)的初始值為0vector<int> v2{10}; //v2有1個(gè)元素,初始值為10vector<int> v3(10,1); //v1有10個(gè)元素,每個(gè)的初始值為1vector<int> v4{10,1}; //v2有2個(gè)元素,初始值為10、1vector支持的操作v.empty() //如果v不含有任何元素,返回真;否則為假v.size() //返回v中元素的個(gè)數(shù)v.push_back(t) //向v的尾端添加一個(gè)值為t的元素v[n] //返回v中第n個(gè)位置上元素的引用v1 = v2 //用v2中元素的拷貝替換v1中的元素v1 = {a,b,c...} //用列表中元素的拷貝替換v1中的元素v1 == v2 //v1 和v2相等當(dāng)且僅當(dāng)它們?cè)財(cái)?shù)量相同且對(duì)應(yīng)位置的元素之相同v1 != v2 <, <=, >, >= //以字典順序進(jìn)行比較不可以用下表形式添加元素,只能用push_back(t)!!!只能對(duì)確知已存在的元素位置進(jìn)行下標(biāo)操作!!!4.內(nèi)聯(lián)函數(shù)inline
調(diào)用函數(shù)有很多有點(diǎn),譬如,易讀性強(qiáng);保持行為的同意,每次相關(guān)操作都能保證按照同樣的方式進(jìn)行;若需要修改計(jì)算過程,只需一次性修改函數(shù)即可;函數(shù)可以被重復(fù)利用,省去了重新編寫的工作量。但是,也有一個(gè)潛在的缺點(diǎn):調(diào)用函數(shù)一般比求等價(jià)表達(dá)式的值要慢,在大多數(shù)機(jī)器上,一次函數(shù)調(diào)用包含了一系列的工作:調(diào)用前要先保存寄存器,并在返回式恢復(fù);可能需要拷貝實(shí)參;程序轉(zhuǎn)向一個(gè)新的位置繼續(xù)執(zhí)行 。
使用內(nèi)聯(lián)函數(shù)(inline)可以避免函數(shù)調(diào)用的開銷。
將函數(shù)制定為內(nèi)聯(lián)函數(shù)(inline),通常是將它在每個(gè)調(diào)用點(diǎn)上“內(nèi)聯(lián)地”展開,假設(shè)我們把上面給定的c程序里的sum函數(shù)定義為內(nèi)聯(lián)函數(shù),那么如下調(diào)用:
sum(&accum, N, data);將在編譯過程中展開成類似于如下形式:
int i;*p = 0;for (i = 0; i < n; ++i) *p = *p + d[i];從而消除了調(diào)用函數(shù)的開銷,在sum函數(shù)的返回類型前面加上關(guān)鍵字 inline,就可以將其聲明成內(nèi)聯(lián)函數(shù)了。
一般,內(nèi)聯(lián)機(jī)制適用于優(yōu)化規(guī)模較小、流程直接、頻繁調(diào)用的函數(shù)。
通過以上幾個(gè)方面,按照題目要求將上述c程序改為c++程序,我的結(jié)果是:
/*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;}第一個(gè)小任務(wù)至此完成,學(xué)習(xí)了輸入輸出流、const、vector類以及inline內(nèi)聯(lián)函數(shù)的用法。
######以上各知識(shí)點(diǎn)均參考《c++ Primer》進(jìn)行學(xué)習(xí)與記錄。#####
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注