知識點學習
Vector容器
-  
vector是C++標准程序庫中的一個類,其定義於
頭文件中,與其他STL組件一樣,ventor屬於STD名稱空間;  -  
ventor是C++標准程序庫里最基本的容器,設計之初是為了改善C語言原生數組的種種缺失和不便,而欲提供一種更有效,安全的數組;
 
根據使用功能大概分為幾個部分
- 訪問元素的方法
 
ven[i] 訪問索引值為i的引用
ven.back() 返回ventor最尾元素的引用
- 新增或移動元素的方法
 
vec.push_back() 新增元素至ventor的尾端,必要時會進行存儲器配置;
vec.pop_back() 刪除ventor最尾端的元素
vec.insert() 插入或多個元素至ventor內的任意位置
vec.erase() 刪除ventor中一個或多個元素
vec.clear() 清空所有元素
- 獲取長度/容量
 
vec.size() 獲取vector目前持有的元素個數
vec.empty() 如果vector內部為空,則傳回true值
-  
迭代(iterator)
 -  
vec.begin() 返回一個迭代器,指向vector第一個元素
 -  
vec.end() 返回一個迭代器,它指向vector最尾端元素的下一個位置(不是最末元素)尾地址不指向任何存儲的元素,而是標志vector的結束。
 
string
string是c++標准程序庫中的一個頭文件,定義了C++標准中的字符串的基本模板類std::basic_string及相關的模板類實例:
經常用到的功能:
- 《字符訪問》
 
string::at
訪問特定字符,帶邊界檢查
string:: operator[]
訪問特定字符
string::front
訪問第一個字符
string::back
訪問最后一個字符
string::data
訪問基礎數組
string:: substr
以子串構造一個新串,參數為空時取全部源串
string:: clear
清空內容
string:: erase
刪除一個或一段字符
string:: push_back
追加1個字符
string:: pop_back
刪除最后1個字符,C++11標准導入
函數傳參定義
- 三種傳參方式比較
 
值傳遞:實參要初始化形參要分配空間,將實參內容拷貝到形參;
指針傳遞:本質仍是值傳遞;
引用傳遞:實參初始化形參的時候不分配空間;
- 函數的返回值
 
通過函數調用使主調函數能得到一個確定的值,這就是函數的返回值
1)函數的返回值是通過函數中的return語句獲得的;
return語句將被調用函數中的一個確定值帶回主調函數中去。
 
        2)函數值的類型,既然函數有返回值,這個值當然應屬於某一個確定的類型,應當在定義函數時指定函數值的類型;
return后面的語句可以是變量、常量、表達式、函數;
 
         
         
        3)在定義函數時指定的函數類型一般應該和return語句中的表達式類型一致。
如果函數值的類型和return語句中表達式的值不一致,則以函數類型為准。對數值型數據,可以自動進行類型轉換。即函數類型決定返回值的類型;
 
        4)對於不帶返回值的函數,應當“void”定義函數為“無類型”(或稱“空類型”),這樣系統就保證不使用函數帶回任何值,即禁止調用函數中使用被調用函數的返回值。
linux GCC編譯方法
 g++ -std=c++11 test.cpp -o test
 
        建議完成《C++ primer 第五版》練習
練習題 4.21
使用條件運算符從ventor 
         
 #include "stdafx.h"
#include <vector>
#include <iostream>
using std::cout;
using std::endl;
using std::vector;
int main() 
{
	vector<int> ivec{1,2,3,4,5,6,7,8,9,10};
	//如果是奇數I乘以2,否則輸出
	for (auto & i : ivec)
	{
		i = (i % 2) ? (i * 2) : i;
	}
	for (auto i : ivec)
	{
		cout << i << "" << endl;
	}
	return 0;
}
 
        5.5 寫一段自己的程序,使用if else語句實現把數字成績轉換成字母成績的要求
int main()
{
	vector<string> scores = { "F","D","C","B","A","A++" };
	int grade{ 0 };
	while (cin >> grade)
	{
		string lettergrade;
		if (grade<60)
		{
			lettergrade = scores[0];
		}
		else 
		{
			lettergrade = scores[(grade - 50) / 10];
			if (grade != 100)
			{
				if (grade % 10 > 7)     //個位數大於7,那么加上 + 號
				{
					lettergrade += "+";
				}
				else if (grade % 10 <3) //個位數小於3,那么加上 - 號
				{
					lettergrade += "-";
				}
			}
		}
		cout << lettergrade << endl;
	}
    return 0;
}
 
        練習題 5.14
編寫一段程序,從標准輸入中讀取若干string對象並查找連續重復出現的單詞。所謂連續重復出現的意思是:一個單詞后面緊跟着這個單詞本身。要求記錄連續重復出現的最大次數以及對應的單詞,如果這樣的單詞存在,輸出重復出現的最大次數,如果不存在,輸出一條信息說明任何單詞都沒有連續出現過。例如,如果輸入時
 how now now now brown cow cow
 那么輸出應該表明單詞now連續出現了3次
#include "stdafx.h"
#include <string>
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::string;
string pre_word, word, max_repeat_word;
int repeat_time = 0, max_repeat_time = 0;
int main()
{
	while (cin>>word)
	{
		if (word == pre_word)
		{
			++repeat_time;
		}
		else 
		{
			repeat_time = 1;
			pre_word = word;
		}
		if (max_repeat_time < repeat_time)
		{
			max_repeat_time = repeat_time;
			max_repeat_word = pre_word;
		}
		if (max_repeat_time > 4)
		{
			break;
		}
	}
	if (max_repeat_time<=1)
	{
		cout << "no word was repeated" << endl;
	}
	else
	{
		cout << "the word '" << max_repeat_word << "' occurred " << max_repeat_time << " times " << endl;
	}
    return 0;
}
 
        練習題 5.17
假設有兩個包含整數的vector對象,編寫一段程序,檢驗其中一個vector對象是否是另一個的前綴。為了實現這一目標,對於兩個不等長的vector對象,只需挑出長度較短的那個,把它的所有元素和另一個vector對象比較即可。例如如果兩個vector對象的元素分別是0、1、1、2和0、1、1、2、3、5、8,則程序的返回結果應該為真;
#include "stdafx.h"
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
int main()
{
	vector<int> vec1{ 0,1,1,2 };
	vector<int> vec2{ 0,1,1,2,3,5,8 };
	auto size = vec1.size() < vec2.size() ? vec1.size() : vec2.size();
	for (decltype(vec1.size()) i = 0 ; i != size; ++i)
	{
		if (vec1[i] != vec2[i])
		{
			cout << "false" << endl;
			return 0;
		}
	}
	cout << "true" << endl;
    return 0;
}
 
        練習題 5.20
編寫一段程序,從標准輸入中讀取string對象的序列直到連續出現兩個相同的單詞或者所有單詞都讀完位置。使用while循環一次讀取一個單詞,當一個單詞連續出現兩次時使用break語句終止循環。輸出連續重復出現的單詞,或者輸出一個消息說明沒有任何單詞是連續重復的。
#include "stdafx.h"
#include <string>
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::string;
int main()
{
	string read, tmp;
	while (cin >> read)
	{
		if (read == tmp)
		{
			break;
		}
		else 
		{
			tmp = read;
		}
	}
	//輸入流的末尾內容
	if (cin.eof())
	{
		cout << "no word was repeated." << endl;
	}
	else 
	{
		cout << read << " occurs twice in succession." << endl;
	}
    return 0;
}
 
        第6章函數
練習題 6.4
編寫一個與用戶交互的函數,要求用戶輸入一個數字,計算生成該數字的階乘,在main函數中調用該函數,計算階乘結果有多少個0
int jiecheng(int chengshu)
{
	int Sum = 1;
	int nCount = 0;
	for (int i=1;i<=chengshu;i++)
	{
		Sum = i*Sum;
	}
	cout << endl;
	cout << "階乘數" << Sum;
	for (;Sum;)
	{
		if (Sum%10==0)
		{
			nCount++;
		}
		Sum = Sum / 10;
	}
	return nCount;
}
int _tmain(int argc, _TCHAR* argv[])
{
	int nNum;
	cin >> nNum;
	nNum = jiecheng(nNum);
	cout << endl;
	cout << nNum;
	return 0;
}
 
        練習題 6.10
編寫一個函數,使用指針形參交換兩個數的值,在函數中調用並輸出交換后的結果;
void swap(int * lhs, int * rhs)
{
	int tmp;
	 tmp = *lhs;
	*lhs = *rhs;
	*rhs = tmp;
}
int _tmain(int argc, _TCHAR* argv[])
{
	int nNumA = 10;
	int nNumB = 20;
	swap(&nNumA, &nNumB);
	cout << nNumA << " " << nNumB;
	return 0;
}
 
        練習題 6.12
使用引用而非指針交換兩個整數的值,那種方式比較易於使用呢?
- 拷貝大的類類型對象或者容器對象比較低效,當某種類型不支持拷貝操作時,函數只能通過引用形參訪問該類型的對象;
 - 引用一經初始化不能再引用其他變量,而指針可以(非const指針)
 
#include <iostream>
#include <string>
void swap(int& lhs, int& rhs)
{
    int temp = lhs;
    lhs = rhs;
    rhs = temp;
}
int main()
{
    for (int left, right;
         std::cout << "Please Enter:\n", std::cin >> left >> right;) {
        swap(left, right);
        std::cout << left << " " << right << std::endl;
    }
    return 0;
}
 
        練習題 6.17
編寫一個函數,判斷string對象中是否有大寫字母,編寫另外一個函數把string對象全都改成小寫形式。這兩個函數中你使用的形參類型相同嗎?
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
bool hasUpercase(const string & str) 
{
	for (auto c :str)
	{
		if (isupper(c))
		{
			return true;
		}
		
	}
	return false;
}
const string & makeLowercase(string & str) 
{
	for (auto & c : str)
	{
		if (isupper(c))
		{
			c = tolower(c);
		}
	}
	return str;
}
int _tmain(int argc, _TCHAR* argv[])
{
	string str("Hello World");
	cout << "類型是否是大寫" << endl;
	cout << hasUpercase(str) << endl;
	
	cout << "轉換小寫函數";
	cout << makeLowercase(str) << endl;
	return 0;
}
 
        練習題 6.22
編寫一個函數,令其交換兩個init指針;
#include "stdafx.h"
#include <windows.h>
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
void swap(int * & lft, int * & rht) 
{
	auto tmp = lft;
	lft = rht;
	rht = tmp;
}
int _tmain(int argc, _TCHAR* argv[])
{
	int i = 42;
	int j = 99;
	auto lft = &i;
	auto rht = &j;
	swap(lft, rht);
	cout << *lft << "  " << *rht << endl;
	return 0;
}
 
        練習題 6.36
編寫一個函數聲明,使其返回數組的引用並且該數組包含10個string對象,不要尾置返回類型、decltype或者類型別名;
string (&func(string (&arrStr)[10]))[10]
 
       