知識點學習
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]