1. using聲明具備以下的形式:ios
using namespace::name;
1. C++標準一方面對庫類型所提供的操做作了規定,另外一方面也對庫的實現作出了性能上的要求,因此,在通常的應用場合,標準庫類型都有足夠的效率。express
2. 當用一個字符串字面值初始化string對象時,除了最後那個空字符外其餘全部的字符都會被拷貝到新建立的string對象中去。數組
3. 若是使用等號初始化一個變量,實際上執行的是拷貝初始化。若是不使用等號,則執行的是直接初始化:函數
string s1 = "hi, ya"; // 拷貝初始化 string s2(10, 'c'); // 直接初始化
4. 在執行讀取string的操做時,string對象會自動忽略開頭的空白(即空格符、換行符、製表符等)並從第一個真正的字符開始讀起,直到碰見下一處空白爲止:oop
// 若是咱們輸入" Hello World! ",輸出將是"Hello",沒有任何空格
string s; cin >> s; cout << s << endl;
5. string::size_type是一個無符號類型的值,並且能足夠存放下任何string對象的大小。須要注意的是,string類的size函數的返回值類型是string::size_type,因爲它是一個無符號類型的值,因此切勿在表達式中將它與有符號類型混用,由於有符號類型會被自動地轉換成無符號類型,致使不容易發現的錯誤。性能
6. 當把string對象和字符字面值及字符串字面值混在一條語句中使用時,必須確保每一個加法運算符的兩側的運算對象至少有一個是string:spa
string s1 = "hello"; string s2 = s1 + ", world!"; // 正確
string s3 = "hello" + ", world" + s1; // 錯誤,不能把字面值直接相加
7. 由於某些歷史緣由,也爲了與C兼容,因此C++語言中的字符串字面值並非標準庫類型string,切記,它們是不一樣的類型。設計
8. C++11提供了一種新的語句:range for語句,這種語句遍歷給定序列中的每一個元素並對每一個元素執行某種操做,語法形式是:指針
for ( declaration : expression ) { statement }
其中,expression部分表示一個序列對象,declaration部分負責定義一個變量,用於訪問序列中的元素,每次迭代,declaration定義的變量就會被初始化爲expression部分的下一個元素值:code
string str = "Hello"; for ( auto c : str ) { std::cout << c << std::endl; }
1. 模板自己不是類或函數,能夠將模板看做爲編譯器生成類或函數編寫的一份說明。編譯器根據模板建立類或函數的過程稱爲實例化。
2. vector能容納絕大多數類型的對象做爲其元素,可是由於引用不是對象,因此不存在包含引用的vector。
3. C++11提供了一種新的初始化vector的方法,稱爲列表初始化:
vector<int> values = { 1, 2, 3, 4 };
4. 咱們能夠只提供vector對象容納的元素數量而省去初始值:
vector<int> values(10); // 建立10個int類型的對象
此時庫會建立一個值初始化的元素初值,並把它賦給容器中的全部元素。所謂值初始化,就是針對內置類型,將會被初始化爲0。而針對類類型,將會使用默認構造函數進行初始化。
5. 若是在初始化vector時使用了列表初始化的方式,可是提供的值又不能用來執行列表初始化,那麼編譯器會嘗試用其餘方式來初始化vector:
vector<string> v1{ "hello" }; // 列表初始化 // 沒法執行列表初始化,由於int對象10不能做爲string對象的初始值,編譯器將構造有10個值爲hello的string對象的vector vector<string> v2{ 10, "hello" };
6. C++標準要求vector應該能在運行時高效快速地添加元素。所以既然vector對象能高效地增加,那麼在定義vector對象的時候設定其大小也就沒有什麼必要了,事實上若是這麼作可能性能反而更差。
7. 須要注意的是,若是循壞體內部包含有向vector對象添加元素的語句,則不能使用範圍for循環,而且在使用其餘循環時,要確保所寫的循環對於vector大小的處理正確無誤。
8. 只有當元素的值可比較時,vector對象才能被比較。
1. 全部標準庫容器均可以使用迭代器,可是其中只有少數幾種才同時支持下標運算符。
2. 迭代器有有效和無效之分:有效的迭代器或者指向某個元素,或者指向容器中尾元素的下一位置。其餘全部狀況都屬於無效。
3. end函數返回的迭代器常被稱爲尾後迭代器,它並不實際指示某個元素。
4. 試圖解引用一個無效的迭代器或者一個尾後迭代器都是致使未定義的行爲。
5. 全部標準庫容器的迭代器都定義了==和!=運算符,可是它們中的大多數都沒有定義<運算符。因此,儘量在使用迭代器時養成使用==和!=運算符的習慣。
6. begin和end運算符返回的具體類型由對象是不是常量決定,若是對象是常量,則返回const_iterator;不然就返回iterator。在C++11中,引入了兩個新函數,cbegin和cend,不管對象是不是常量,cbegin和cend都返回const_iterator。
7. 任何一種可能改變vector對象元素數量的操做,均可能使該vector對象的迭代器失效。
8. 兩個迭代器相減的結果的類型是名爲difference_type的帶符號整型數。
1. 數組是一種複合類型,聲明形式如a[b],a是數組的名字,b是數組的維度。維度也屬於數組類型的一部分,編譯時維度必須是已知的,也就是說,維度必須是一個常量表達式。
2. 定義數組的時候必須指定數組元素的類型,不容許使用auto關鍵字由初始值列表推斷數組元素的類型。
3. 數組中的元素爲對象,因此不存在引用的數組。默認狀況下,數組中的元素執行默認初始化。
4. 當用列表初始化數組時,若是沒有指定維度,編譯器會根據初始值的數量計算並推測出維度。若是指定了維度,那麼初始值的數量不能超過維度指定的大小。若是維度比列表中的初始值數量大 ,則用提供的初始值初始化靠前的元素,剩下的元素執行值初始化:
const unsigned sz = 3; int a1[sz] = { 0, 1, 2 }; int a2[] = { 0, 1, 2 }; // 維度是3的數組
int a3[5] = { 0, 1, 2}; // 等價於a3[] = { 0, 1, 2, 0, 0 };
string a4[3] = { "hi", "bye" }; // 等價於a4[3] = { "hi", "bye", "" };
int a5[2] = { 0, 1, 2 }; // 錯誤,初始值過多
5. 當使用字符串字面值初始化字符數組時,要注意在字符串字面值的結尾處還有一個空字符:
char a1[] = "C++"; // a1包含四個字符,分別是'C' '+' '+' '\0' char a2[6] = "Daniel"; // 錯誤,沒有空間能夠存放結尾的空字符
6. 在使用數組下標的時候,一般將其定義爲size_t類型,它是一種機器相關的無符號類型,被設計得足夠大以便能表示內存中任意對象的大小。
7. 在不少用到數組名字的地方,編譯器都會自動地將其替換爲一個指向數組首元素的指針:
int a[] = { 1, 2, 3 }; int *p = a; // 等價於int *p = &a[0];
這一事實有不少含義,其中之一是當使用數組做爲一個auto變量的初始值時,獲得的類型是指針而非數組:
int a[] = { 1, 2 }; auto a2(a); // a2的類型是int*
而當使用decltype聲明變量時,轉換則不會發生:
int a[] = { 1, 2 }; decltype(a) a2 = { 2, 3 }; // a2是一個含有2個元素的數組
8. C++11引入了兩個名爲begin和end的函數,它們的功能與標準庫容器中的begin和end相似:
int a[] = { 1, 2, 3 }; int *beg = begin(a); // beg指向數組a的首元素 int *last = end(a); // last指向數組a的尾元素的下一位置
9. 兩個指向同一個數組當中的元素的指針相減的結果類型是一種名爲ptrdiff_t的標準庫類型,它是一種與機器實現有關的有符號整數類型,它的空間足夠大,可以表示任意兩個指向同一個數組當中的元素的指針之間的距離。
10. 可使用下標運算來訪問數組中的元素,它與標準庫類型string和vector的下標運算的區別在於:標準庫類型限定使用的下標必須是無符號類型,而數組的下標運算沒有這個要求:
int arr[] = { 0, 2, 4 }; int *p = &arr[2]; int k = p[-2]; // p[-2]是arr[0]表示的那個元素
11. string對象提供了成員函數c_str用於返回一個以空字符結尾的字符數組,須要注意的是,沒法保證c_str返回的數組一直有效,任何後續的對string對象的修改均可能讓它變得無效。
1. 可使用下標運算符來訪問多維數組的元素,此時數組的每一個維度對應一個下標運算符。若是表達式含有的下標運算符數量和數組的維度同樣多,該表達式的結果將是給定類型的元素;反之,若是表達式含有的下標運算符數量比數組的維度小,則表達式的結果將是給定索引處的一個內層數組:
int arr_0[3][4] = { 0 }; int arr_1[10][20][30] = { 0 }; arr_0[0][1] = arr_1[1][2][3]; // 把arr_1中的某個元素賦值給arr_0中的某個元素 int (&arr_2)[4] = arr_0[0]; // 把arr_2綁定到arr_0的第一個4元素數組上
2. 當使用範圍for語句處理多維數組時,除了最內層的循壞外,其餘全部循壞的控制變量都應該是引用類型,這是由於若是不用引用類型,編譯器會初始化控制變量爲指向數組首元素的指針:
int arr[2][3] = { 0 }; for ( auto row : arr ) { for ( auto col : row ) { } } // 上面的程序將沒法經過編譯,由於row將被初始化爲指向數組arr首元素的指針,所以致使auto col : row語句是非法的,因此記得使用引用類型: for ( const auto &row : arr ) { for ( auto col : row ) { } }
Q_1. Write a program to read two strings and report whether the strings are equal. If not, report which of the two is larger. Now, change the program to report whether the strings have the same length, and if not, report which is longer.
A_1.
#include <iostream> #include <string> int main() { std::string str_1, str_2; std::cin >> str_1 >> str_2; if ( str_1 == str_2 ) { std::cout << "str_1 and str_2 are equal" << std::endl; } else { if ( str_1 > str_2 ) { std::cout << "str_1 is larger" << std::endl; } else { std::cout << "str_2 is larger" << std::endl; } } return 0; }
#include <iostream> #include <string> int main() { std::string str_1, str_2; std::cin >> str_1 >> str_2; if ( str_1.size() == str_2.size() ) { std::cout << "str_1 and str_2 have the same length" << std::endl; } else { if ( str_1.size() > str_2.size() ) { std::cout << "str_1 is longer" << std::endl; } else { std::cout << "str_2 is longer" << std::endl; } } return 0; }
Q_2. Write a program to read strings from the standard input, concatenating what is read into one large string. Print the concatenated string. Next, change the program to separate adjacent input strings by a space.
A_2.
#include <iostream> #include <string> int main() { std::string str_1, str_2; while ( std::cin >> str_1 ) { str_2 += str_1; } std::cout << str_2; return 0; }
#include <iostream> #include <string> int main() { std::string str_1, str_2; std::cin >> str_2; // 讀取第一個字符串,防止在第一個字符串以前出現空格 while ( std::cin >> str_1 ) { str_2 = str_2 + ' ' + str_1; } std::cout << str_2; return 0; }
Q_1. Use a range for to change all the characters in a string to X.
A_1.
#include <iostream> #include <string> int main() { std::string str = "Hello"; for ( auto &c : str ) { c = 'X'; } std::cout << str << std::endl; return 0; }
Q_2. Rewrite the program in the first exercise, first using a while
and again using a traditional for
loop.
A_2.
#include <iostream> #include <string> int main() { std::string str = "Hello"; decltype(str.size()) index = 0; while ( index < str.size() ) { str[index++] = 'X'; } std::cout << str << std::endl; return 0; }
#include <iostream> #include <string> int main() { std::string str = "Hello"; for ( decltype(str.size()) index = 0; index < str.size(); ++index ) { str[index] = 'X'; } std::cout << str << std::endl; return 0; }
Q_3. Write a program that reads a string of characters including punctuation and writes what was read but with the punctuation removed.
A_3.
#include <iostream> #include <string> #include <cctype> int main() { std::string str; if ( std::cin >> str ) { std::string newStr; for ( const auto &c : str ) { if ( !std::ispunct(c) ) { newStr += c; } } std::cout << newStr << std::endl; } return 0; }
Q_1. Write a program to read a sequence of ints from cin and store those values in a vector.
A_1.
#include <iostream> #include <vector> int main() { int value; std::vector<int> vInts; while ( std::cin >> value ) { vInts.push_back( value ); } return 0; }
Q_1. Read a sequence of words from cin and store the values a vector. After you've read all the words, process the vector and change each word to uppercase. Print the transformed elements, eight words to a line.
A_1.
#include <iostream> #include <string> #include <vector> int main() { std::string value; std::vector<std::string> vWords; while ( std::cin >> value ) { vWords.push_back( value ); } for ( auto &rWord : vWords ) { for ( auto &rChar : rWord ) { rChar = toupper( rChar ); } } return 0; }
Q_2. Read a set of integers into a vector. Print the sum of each pair of adjacent elements. Change your program so that it prints the sum of the first and last elements, followed by the sum of the second and second-to-last, and so on.
A_2.
#include <iostream> #include <vector> int main() { int value; std::vector<int> vInts; while ( std::cin >> value ) { vInts.push_back( value ); } // 若是沒有元素或只有一個元素... if ( vInts.size() <= 1 ) { // ...直接返回 return 0; } for ( std::vector<int>::size_type index = 0; index < vInts.size() - 1; ++index ) { std::cout << "sum: " << vInts[index] + vInts[index + 1] << std::endl; } return 0; }
#include <iostream> #include <vector> int main() { int value; std::vector<int> vInts; while ( std::cin >> value ) { vInts.push_back( value ); } // 若是沒有元素或只有一個元素... if ( vInts.size() <= 1 ) { // ...直接返回 return 0; } for ( std::vector<int>::size_type index = 0; (index * 2) < vInts.size(); ++index ) { std::cout << "sum: " << vInts[index] + vInts[vInts.size() - 1 - index] << std::endl; } return 0; }
Q_1. Write a program to create a vector with ten int elements. Using an iterator, assign each element a value that is twice its current value. Test your program by printing the vector.
A_1.
#include <iostream> #include <vector> int main() { std::vector<int> vInts{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; for ( auto iter = vInts.begin(); iter != vInts.end(); ++iter ) { (*iter) *= 2; } for ( auto value : vInts ) { std::cout << value << std::endl; } return 0; }
Q_1. Redo the last exercise from § 3.3.3 (p. 105) using iterators.
A_1.
#include <iostream> #include <vector> int main() { int value; std::vector<int> vInts; while ( std::cin >> value ) { vInts.push_back( value ); } // 若是沒有元素或只有一個元素... if ( vInts.size() <= 1 ) { // ...直接返回 return 0; } for ( auto iter = vInts.cbegin(); iter != vInts.end() - 1; ++iter ) { std::cout << "sum: " << (*iter) + *(iter + 1) << std::endl; } return 0; }
#include <iostream> #include <vector> int main() { int value; std::vector<int> vInts; while ( std::cin >> value ) { vInts.push_back( value ); } // 若是沒有元素或只有一個元素... if ( vInts.size() <= 1 ) { // ...直接返回 return 0; } for ( auto iter = vInts.cbegin(), rIter = vInts.cend() - 1; iter <= rIter; ++iter, --rIter ) { std::cout << "sum: " << (*iter) + (*rIter) << std::endl; } return 0; }
Q_2. Rewrite the grade clustering program from § 3.3.3 (p. 104) using iterators instead of subscripts
A_2.
#include <iostream> #include <vector> int main() { std::vector<unsigned> scores( 11, 0 ); unsigned grade; while ( std::cin >> grade ) { if ( grade <= 100 ) { (*(scores.begin() + grade/10))++; } } return 0; }
Q_1. Write a program to define an array of ten ints. Give each element the same value as its position in the array.
A_1.
int main() { int values[10]; for ( int index = 0; index < 10; ++index ) { values[index] = index; } return 0; }
Q_2. Copy the array you defined in the previous exercise into another array. Rewrite your program to use vectors.
A_2.
int main() { int values[10]; for ( int index = 0; index < 10; ++index ) { values[index] = index; } int copyTo[10]; for ( int index = 0; index < 10; ++index ) { copyTo[index] = values[index]; } return 0; }
#include <iostream> #include <vector> int main() { std::vector<int> values( 10 ); for ( int index = 0; index < 10; ++index ) { values[index] = index; } std::vector<int> copyTo( values ); return 0; }
Q_1. Using pointers, write a program to set the elements in an array to zero.
A_1.
#include <iostream> #include <iterator> int main() { const unsigned ARRAY_SIZE = 10; int arr[ARRAY_SIZE]; int *pValue = std::begin( arr ); while ( pValue != std::end(arr) ) { *pValue = 0; ++pValue; } return 0; }
Q_2. Write a program to compare two arrays for equality. Write a similar program to compare two vectors.
A_2.
#include <iostream> #include <iterator> int main() { int arr_0[] = { 0, 1, 2 }; int arr_1[] = { 0, 1, 2, 4 }; int *pValue_0 = std::begin( arr_0 ); int *pValue_1 = std::begin( arr_1 ); while ( (pValue_0 != std::end(arr_0)) && (pValue_1 != std::end(arr_1)) && (*pValue_0 == *pValue_1) ) { ++pValue_0; ++pValue_1; } if ( (pValue_0 == std::end(arr_0)) && (pValue_1 == std::end(arr_1)) ) { std::cout << "數組相等" << std::endl; } else { std::cout << "數組不相等" << std::endl; } return 0; }
#include <iostream> #include <vector> int main() { std::vector<int> vInts_0{ 0, 1, 2, 3 }; std::vector<int> vInts_1{ 1, 1, 2 }; if ( vInts_0 == vInts_1 ) { std::cout << "vector相等" << std::endl; } else { std::cout << "vector不相等" << std::endl; } return 0; }
Q_1. Write a program to define two character arrays initialized from string literals. Now define a third character array to hold the concatenation of the two arrays. Use strcpy and strcat to copy the two arrays into the third.
A_1.
#include "stdafx.h" #include <iostream> int main() { const char *pszValue_0 = "Hello "; const char *pszValue_1 = "World!"; char *pszFinalValue = new char[strlen(pszValue_0) + strlen(pszValue_1) + 1]; strcpy( pszFinalValue, pszValue_0 ); strcat( pszFinalValue, pszValue_1 ); delete[] pszFinalValue; pszFinalValue = NULL; return 0; }