C++ primer 详解(第三章)
3.1 命名空間的using聲明
1.在初學C++的時候,寫的第一條代碼便是在控制臺輸出一個Hello Word,而在#include后面的第一句話便是using namespace std;,那時候只知道不寫這句代碼就會報錯,但是不知為什么。這句話的含義是:這個文件會使用到std標準庫中的名字。
2.using聲明有兩種方式:
using namespace std; //這種是最方便的,但是可能會包含太多
using std::cout;? //這種是指定需要使用std中哪個名字
3.注意頭文件中不應該包含using聲明,因為頭文件被包含的時候,會將里面的內容拷貝到引用它的文件里面去,如果頭文件中有using聲明,那么每個使用了該頭文件的文件都會有這個聲明,在一些程序中,可能會引起一些名字沖突。
3.2標準庫類型string
3.2.1定義和初始化string對象
默認初始化:string s1;? //使用string類默認初始化,s1被初始化為空
拷貝初始化:string s2=“value”;
直接初始化:string s3(“value”);
每個值都相同的直接初始化:string s4(10,’c’);
每個值都想同的拷貝初始化:string s5=string(10,’c’);
2.拷貝初始化和直接初始化的區別:在轉載的一篇博客上有詳解,這里大概說一下:拷貝初始化會首先生成一個臨時對象,然后調用拷貝構造函數,將臨時對象拷貝到需要復制的那個對象中。而直接初始化是直接調用與實參所匹配的構造函數。
3.2.2sting對象上的操作
1.可讀寫:string對象重載了<<操作符,可以使用cout<<在控制臺打印string對象,(在這里說明一下使用cout,cin一個string對象和一個char數組的區別,string對象在創建的時候就已經保存了長度,而且在輸出的時候也是根據string對象所保存的長度進行輸出,這和char數組的輸出不一樣。)
2.string對象在使用cin>>string賦值的時候,會忽略掉開頭的空格,結束于下一個空格。
3.可以使用getline獲取一行string對象,直到遇到回車符(回車符最后會被去掉)
4..empty()(判斷是否為空)操作和.size()(獲取string字符的個數)。size返回的是string::type_size類型,只知道它是一個無符號類型,不要和int類型混用。
5.string對象可以相互比較,比較規則:首先如果長度和對應的1字母都相同,那么這兩個string對象就是完全相同的,然后如果字母有不相同的那么就按字典序比較第一對不同的字母(字典排序越靠后越大),如果字母完全相同就比較長度。
6.string對象可以用“+”拼接。
7.對string對象中的元素進行處理:
1.遍歷使用for(auto c :str) cout<<c<<endl;
(這里的for應該把它當成一個函數來使用,因此若想在循環里面改變c的值,則使用(for(auto &c:str)))
2.如果不想使用遍歷,而是只處理一部分字符,可以使用下標運算符:[];
3.3Vector
Vector的英文翻譯為向量,在這里作為容器。
Vector是應用的模版實現,因此每次在使用的時候需要具體類型實例化后使用。
3.3.1定義和初始化vector對象
默認初始化:vector<T> v1;
拷貝初始化:vector<T> v2=v1;
直接初始化:vector<T> v3(v2);
指定含有多個不相同初始值的初始化:vector <T> v4{a,b,c,d};
指定含有多個相同初始值的初始化:vector<T> v5(10,-1);
而列表初始化用于:
3.3.3對Vector的一些操作
1..push_back()向尾端添加一個元素
2.vector也能使用for循環遍歷
3.vector的大小類型:vector<int>::size_type.
4.vector也可以比較大小,規則和string一樣。
5.只能用下表操作符訪問已經存在的元素,需要添加元素等則使用push_back();
3.4迭代器Iterator
迭代器性質和指針差不多,因此可以按照指針的性質來理解
3.4.1使用迭代器
1.V.begin()和V.end(),其中V.begin()返回一個指向容器第一個元素的迭代器,V.end()返回指向最后一個元素的下一個位置。
2.如果容器為空,則begin()=end().=。
3.如果不明白begin()和end()的返回值,可以用auto。
4.迭代器也可以使用*操作符解引用,也可以使用++運算符。
5.在條件運算中,對于容器來說盡量使用!=代替大于或小于,因為有些容器并沒有定義大于小于,但是定義等于和不等于確很簡單。
6.理解const_iterator與const iterator與typedef定義的類型一樣,const iterator const修飾的時iterator這個指針,因此說明的這個指針是常量。而單獨定義的const_iterator是指所指對象是const的。
7.begin()和end()若對象是普通對象返回的也是一個普通迭代器,若對象是常量,返回const_iterator。若想一直得到一個指向這個對象,但是不修改這個對象的值的指針,用cbegin();
8.使用指針訪問成員函數操作符“->”的由來:使用指針,需要解引用:*it,再使用點操作符,但是由于優先級的原因,需要打上括號:(*it).begin();為了簡便,把括號加*操作符符加點操作符簡化為“->”;it->begin();
9.指針可以使用++運算符來移動一個類型的位子。比如一個int類型,++一次,移動4字節(在int占32位的情況下。)
10.謹記:但凡使用了迭代器的循環體,都不能改變這個容器中元素的個數。
3.4.2迭代器的運算
1.迭代器之間可以相減,得到的結果兩個元素之間的距離(可以為負數)
2.迭代器也可以和指針一樣,使用++操作符移動一個元素之間的距離。
3.5數組
1.數組和Vector有差不多的性質,可以使用下標隨機訪問,與Vector不同的是,數組的大小是確定的,也不能隨意改變它的大小,性能高但是不靈活。
2.對于Vector和數組的選擇,如果不清楚元素的確切個數,選擇使用vector,如果能夠確定元素個數的話,使用數組。
3.5.1 定義和初始化內置數組
int arr[42]?? //含有42個整形元素的數組;
int *arr[10]? //含有10個整型指針的數組
例如:const int sz=5;
???? int arr[sz];
是可以的。
char a1[]={‘C’,’+’,’+‘,‘\0’};
char a2[]=”C++”;? //a2的維度為4;
char a3[3]=”C++”;//錯誤:”C++”,這個字符串是4個元素。
char a4[]={‘C’,’+’,’+’}; //這種定義是允許的,但是后面會有一系列的問題。
int a[]={0,1,2};
int a2[]=a;?? //錯誤,不允許將一個數組作為初始值給另外一個數組
a2=a;????? //錯誤,不能把一個數組直接賦值給另外一個數組
?? int *ptrs[10];? //這個數組有10個元素,每個元素都是int指針。
int &refs[10];? //錯誤,數組里面應該是對象,不能是引用。(引用不占空間)
int (*Parray)[10]=&arr; //Parray指向一個含有10個int類型的元素的數組。
int (&arrRef)[10]=arr; //arrRef引用一個含有10個整型元素的數組。
?? int *(&arry)[10]=ptrs;//arry引用一個含有10個指向int類型的指針的數組
//在編譯器上試了一下把括號去掉的效果
int *&array[10]=ptrs;編譯器會報錯了,報錯內容是不允許定義引用的數組。
繼續測試: int **array[10];這樣的數組初始化必須是{ptr1,ptr2,ptr3…};
因此如果對于定義數組,不打括號的話,數組里面的元素應該是數組名字左邊的所有聲明符加起來。
?
書上說,對于數組的理解應該按照由內到外理解。但是按照之前對指針類型的分析,這里可以這樣分析。首先看這個數組里面的元素類型是什么:int *ref[10];
可以這樣看(int *)ref[10];也就是說這個數組里面的元素都是指針。而
int (*Parray)[10]=&arr;這種類型,首先數組里面的元素是int型的,再看parray它就是一個指針了。指向這個數組。
?
3.5.2訪問數組元素
1.和其他數組元素一樣,數組也有自己獨有的下標類型:size_t類型,這是一種和機器相關的無符號類型。
2.與vector相比,數組的下標類型可以是有符號類型,也可以是無符號類型,但是vector的下標必須是無符號類型。
3.5.3指針和數組
在C++中,指針和數組有很多緊密的聯系。在很多時候,使用數組的時候,編譯器會將它轉換為指向數組首元素的指針。
int ia[]={0,1,2,3,4,5,6,7,8,9};
auto ia2(ia);? //ia是一個整型指針,指向ia的第一個元素
decltype(ia) ia3={0,1,2,3,4,5,6,7,8,9}; //ia是一個數組。
//思考為什么:因為ia2是用數組初始化的,前面提到不能用數組初始化一個數組,因此auto會將其轉化為指針。
3.5.4C風格字符串
1.C風格字符串:以‘\0‘結尾的字符串。
2.C風格字符串的函數:strlen(p),strcmp(p1,p2);strcat(p1,p2);strcpy(p1,p2);
3.在很多編譯器中,使用以上函數會出現waring或者報錯,這是因為以上函數都不會去驗證這個字符串是否是標準的C風格字符串。也就是如果這個字符串不是以‘\0’結尾,它會沿著這個字符串所在的內存一直向后找,直到找到‘\0’;
4.對于大多數情況,字符串使用string會更加的安全。
3.5.5與舊代碼的接口
1.版本總是會兼容以前的內容,因此string可以很容易轉換為C風格字符串。使用.c_str();就可以,但是這個函數只是返回一個C風格字符串,而沒有改變它本身,因此想一直使用它返回的字符串,最好拷貝下來。
2.想將C風格字符串轉換為string類型,可以直接用C風格字符串初始化string類型。
3.數組也可以用來初始化vector。傳入頭指針和尾指針即可:
?int int_arr[]={0,1,2,3,4};
vector<int> ivec(begin(int_arr),end(int_arr));
3.6多位數組
對于多維數組,沒什么好說的,只要記得,多位數組僅僅是數組里面的元素是數組,其他就都很好理解了。
可以使用類型別名簡化多位數組的指針
using int_array=int[4];
typedef int int_attay[4];
int_array *p;//p是一個二維數組的指針。
?
轉載于:https://www.cnblogs.com/citron/p/6145291.html
總結
以上是生活随笔為你收集整理的C++ primer 详解(第三章)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 时代英语报答案六下34期
- 下一篇: Google-GLog编译以及使用