文章目錄
- 目錄
- 數組
- 1.數組的申明
- 2.數組的初始化
- 3.二維數組
- 4.指向數組的指針
- 5.傳遞數組給函數
- 動態內存
- 1.new ,delete運算符
- 2.數組的動態內存分配
- vector
- 1.vector基本操作
- 2.vector使用
- 3.vector動態二維數組 初始化和賦值
目錄
- 數據結構:
- 邏輯結構:數組,棧,隊列,字符串,樹,圖
- 存儲結構:順序存儲,鏈式存儲
- C++常用的數據結構有:string , stack , queue , deque , vector , list , map , iterators.
數組
1.數組的申明
#include <iostream>
using namespace std;#include <iomanip>
using std::setw;int main ()
{int n[ 10 ]; // n 是一個包含 10 個整數的數組// 初始化數組元素 for ( int i = 0; i < 10; i++ )n[ i ] = i + 100; // 設置元素 i 為 i + 100cout << "Element" << setw( 13 ) << "Value" << endl;// 輸出數組中每個元素的值 for ( int j = 0; j < 10; j++ )cout << setw( 7 )<< j << setw( 13 ) << n[ j ] << endl;}
運行結果:
Element Value
0 100
1 101
2 102
3 103
4 104
5 105
6 106
7 107
8 108
9 109
2.數組的初始化
(1)Array 直接初始化 char 數組是特殊的,這種初始化要記得字符是以一個 null 結尾的
char a1[] = {'C', '+', '+'}; // 初始化,沒有 nullchar a2[] = {'C', '+', '+', '\0'}; // 初始化,明確有 nullchar a3[] = "C++"; // null 終止符自動添加
const char a4[6] = "runoob"; // 報錯,沒有 null 的位置
a4 是錯誤的,雖然 a4 包括 6 個直接字符,但是 array 大小是 7:6個字符 + 一個null。正確的是:
const char a4[7] = "runoob";
(2)Array 是固定大小的,不能額外增加元素.當我們想定義不固定大小的字符時,可以使用 vector(向量) 標準庫
#include <iostream>
#include <vector>
using namespace std;int main() {// 創建向量用于存儲整型數據vector<int> vec; int i;// 顯示 vec 初始大小cout << "vector size = " << vec.size() << endl;// 向向量 vec 追加 5 個整數值for(i = 0; i < 5; i++)vec.push_back(i);// 顯示追加后 vec 的大小cout << "extended vector size = " << vec.size() << endl;
}
vec 的大小隨著 for 循環的輸入而增大。
執行以上代碼,輸出結果:
vector size = 0
extended vector size = 5
(3)動態數組
動態數組指的是在數組使用的時候才分配存儲空間,而不是像靜態數組那樣一開始就分配好存儲空間的。
靜態 int array[100]; 定義了數組 array,并未對數組進行初始化靜態 int array[100] = {1,2}; 定義并初始化了數組 array動態 int* array = new int[100]; delete []array; 分配了長度為 100 的數組 array動態 int* array = new int[100]{1,2}; delete []array; 為長度為100的數組array初始化前兩個元素
3.二維數組
多維數組最簡單的形式是二維數組。一個二維數組,在本質上,是一個一維數組的列表。聲明一個 x 行 y 列的二維整型數組,形式如下:
type arrayName [ x ][ y ];
其中,type 可以是任意有效的 C++ 數據類型,arrayName 是一個有效的 C++ 標識符。
一個二維數組可以被認為是一個帶有 x 行和 y 列的表格。下面是一個二維數組,包含 3 行和 4 列:
初始化二維數組
int a[3][4] = { {0, 1, 2, 3} , /* 初始化索引號為 0 的行 */{4, 5, 6, 7} , /* 初始化索引號為 1 的行 */{8, 9, 10, 11} /* 初始化索引號為 2 的行 */
};
內部嵌套的括號是可選的
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
訪問二維數組元素
#include <iostream>
using namespace std;int main ()
{// 一個帶有 5 行 2 列的數組int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};// 輸出數組中每個元素的值 for ( int i = 0; i < 5; i++ ){ for ( int j = 0; j < 2; j++ ){cout << "a[" << i << "][" << j << "]: ";cout << a[i][j]<< endl;}}
}
a[0][0]: 0
a[0][1]: 0
a[1][0]: 1
a[1][1]: 2
a[2][0]: 2
a[2][1]: 4
a[3][0]: 3
a[3][1]: 6
a[4][0]: 4
a[4][1]: 8
4.指向數組的指針
數組名是一個指向數組中第一個元素的常量指針(無法對數組名重新賦值)。因此,在下面的聲明中:
double balance[50];
balance 是一個指向 &balance[0] 的指針,即數組 balance 的第一個元素的地址。因此,下面把 p 賦值為 balance 的第一個元素的地址:
double *p;
double balance[10];p = balance;
- 使用數組名作為常量指針是合法的,反之亦然。因此,*(balance + 4) 是一種訪問 balance[4] 數據的合法方式。
- 一旦您把第一個元素的地址存儲在 p 中,您就可以使用 * p、* (p+1)、* (p+2) 等來訪問數組元素
#include <iostream>
using namespace std;int main ()
{// 帶有 5 個元素的雙精度浮點型數組double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};double *p;p = balance;// 輸出數組中每個元素的值cout << "使用指針的數組值 " << endl; for ( int i = 0; i < 5; i++ ){cout << "*(p + " << i << ") : ";cout << *(p + i) << endl;}cout << "使用 balance 作為地址的數組值 " << endl;for ( int i = 0; i < 5; i++ ){cout << "*(balance + " << i << ") : ";cout << *(balance + i) << endl;}return 0;
}
使用指針的數組值
*(p + 0) : 1000
*(p + 1) : 2
*(p + 2) : 3.4
*(p + 3) : 17
*(p + 4) : 50
使用 balance 作為地址的數組值
*(balance + 0) : 1000
*(balance + 1) : 2
*(balance + 2) : 3.4
*(balance + 3) : 17
*(balance + 4) : 50
5.傳遞數組給函數
- C++ 不允許向函數傳遞一個完整的數組作為參數
- 但是,您可以通過指定不帶索引的數組名來傳遞一個指向數組的指針。
如果您想要在函數中傳遞一個一維數組作為參數,您必須以下面三種方式來聲明函數形式參數,這三種聲明方式的結果是一樣的,因為每種方式都會告訴編譯器將要接收一個整型指針。同樣地,您也可以傳遞一個多維數組作為形式參數
方式1: 形式參數是一個指針
void myFunction(int *param){ }
方式2:形參為一個已經定義了大小的數組
void myFunction(int param[10]){ }
方式3: 形式參數是一個未定義大小的數組
void myFunction(int param[]){ }
實例:把數組作為參數,同時還傳遞了另一個參數,根據所傳的參數,會返回數組中各元素的平均值
#include <iostream>
using namespace std;// 函數聲明
double getAverage(int arr[], int size);int main ()
{int balance[5] = {1000, 2, 3, 17, 50}; // 帶有 5 個元素的整型數組double avg;avg = getAverage(balance, 5) ; // 傳遞一個指向數組的指針作為參數 cout << "平均值是:" << avg << endl; // 輸出返回值
}double getAverage(int arr[], int size)
{int i, sum = 0; double avg; for (i = 0; i < size; ++i)sum += arr[i];avg = double(sum) / size;return avg;
}
平均值是:214.4
動態內存
了解動態內存在 C++ 中是如何工作的是成為一名合格的 C++ 程序員必不可少的。C++ 程序中的內存分為兩個部分:
- 棧:在函數內部聲明的所有變量都將占用棧內存。
- 堆:這是程序中未使用的內存,在程序運行時可用于動態分配內存。
很多時候,您無法提前預知需要多少內存來存儲某個定義變量中的特定信息,所需內存的大小需要在運行時才能確定。
- 在 C++ 中,您可以使用特殊的運算符為給定類型的變量在運行時分配堆內的內存,這會返回所分配的空間地址。這種運算符即 new 運算符。
- 如果您不需要動態分配內存,可以使用 delete 運算符,刪除之前由 new 運算符分配的內存。
1.new ,delete運算符
#include <iostream>
using namespace std;int main ()
{double* pvalue = NULL; // 初始化為 null 的指針pvalue = new double; // 為變量請求內存*pvalue = 29494.99; // 在分配的地址存儲值cout << "Value of pvalue : " << *pvalue << endl;delete pvalue; // 釋放內存
}
Value of pvalue : 29495
2.數組的動態內存分配
二維數組
二維數組其實可以看成2個一維的數組,所以初始化也需要分成2步來初始化,先初始化行,然后初始化列。
int **array
// 假定數組第一維長度為 m, 第二維長度為 n// 動態分配空間
array = new int *[m]; //初始化行
//對每行初始化列
for( int i=0; i<m; i++ )
{array[i] = new int [n] ;
}//釋放
for( int i=0; i<m; i++ )
{delete [] arrar[i];
}
delete [] array;
實例
#include <iostream>
using namespace std;int main()
{int **p; int i,j; //p[4][8] //開始分配4行8列的二維數據 p = new int *[4];for(i=0;i<4;i++)p[i]=new int [8];for(i=0; i<4; i++){for(j=0; j<8; j++)p[i][j] = j*i;} //打印數據 for(i=0; i<4; i++){for(j=0; j<8; j++) { if(j==0) cout<<endl; cout<<p[i][j]<<"\t"; }} //開始釋放申請的堆 for(i=0; i<4; i++){delete [] p[i]; }delete [] p;
}
運行結果:
0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7
0 2 4 6 8 10 12 14
0 3 6 9 12 15 18 21
vector
1.vector基本操作
在c++中,vector是一個十分有用的容器。
- 作用:它能夠像容器一樣存放各種類型的對象,簡單地說,vector是一個能夠存放任意類型的動態數組,能夠增加和壓縮數據。
- vector在C++標準模板庫中的部分內容,它是一個多功能的,能夠操作多種數據結構和算法的模板類和函數庫。
實例
#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> vec; // 創建一個向量存儲 intint i;cout << "vector size = " << vec.size() << endl; // 顯示 vec 的原始大小for(i = 0; i < 5; i++) // 推入 5 個值到向量中vec.push_back(i);cout << "extended vector size = " << vec.size() << endl; // 顯示 vec 擴展后的大小for(i = 0; i < 5; i++)cout << "value of vec [" << i << "] = " << vec[i] << endl; // 訪問向量中的 5 個值// 使用迭代器 iterator 訪問值vector<int>::iterator v = vec.begin();while( v != vec.end()) {cout << "value of v = " << *v << endl;v++;}
}
vector size = 0
extended vector size = 5
value of vec [0] = 0
value of vec [1] = 1
value of vec [2] = 2
value of vec [3] = 3
value of vec [4] = 4
value of v = 0
value of v = 1
value of v = 2
value of v = 3
value of v = 4
2.vector使用
特別注意
- 1、如果你要表示的向量長度較長(需要為向量內部保存很多數),容易導致內存泄漏,而且效率會很低;
- 2、Vector作為函數的參數或者返回值時,需要注意它的寫法:
double Distance(vector< int >&a, vector< int >&b) 其中的“&”絕對不能少!!!- 3.vector的元素不僅僅可以是int,double,string,還可以是結構體,但是要注意:結構體要定義為全局的,否則會出錯。
算法
1.使用reverse將元素翻轉,需要頭文件#include< algorithm >
reverse(vec.begin(),vec.end()); //將元素翻轉,即逆序排列!
在vector中,如果一個函數中需要兩個迭代器,一般后一個都不包含
2.使用sort排序:需要頭文件#include< algorithm >,
sort(vec.begin(),vec.end()); //默認是按升序排列,即從小到大
可以通過重寫排序比較函數按照降序比較,如下:
//定義排序比較函數:
bool Comp(const int &a,const int &b)
{return a>b;
}//調用時
sort(vec.begin(),vec.end(),Comp) //這樣就降序排序
3.vector動態二維數組 初始化和賦值
一維數組
#include <iostream>
#include <vector>
using namespace std;int main()
{ vector<int> v={1,2,3};cout<<v[2]<<endl;v.push_back(3);cout<<v[3]<<endl;
}
3
3
二維數組
(1)第1種方法:通過 resize( ) 的形式改變行列數
#include <iostream>
#include <vector>
using namespace std;int main()
{int array_temp[4][4]={1,2,8,9,2,4,9,12,4,7,10,13,6,8,11,15};int i,j;//得到一個 4行4列的數組,通過resize()的形式改變行列數vector<vector<int> > array(4);for(i=0;i<array.size();i++)array[i].resize(4);for(i = 0; i < array.size(); i++){for (j = 0; j < array[0].size();j++)array[i][j] = array_temp[i][j];}cout<<array[2][3]<<endl;
}
(2)第2種方法:通過 push_back( )
#include <iostream>
#include <vector>
using namespace std;int main()
{int array_temp[4][4]={1,2,8,9,2,4,9,12,};int i,j;vector<vector<int> > array;vector<int> a;vector<int> b;for(i=0;i<4;i++)a.push_back(array_temp[0][i]);for(i=0;i<4;i++)b.push_back(array_temp[1][i]);cout<<"a[1]="<<a[1]<<endl;cout<<"b[2]="<<b[2]<<endl;array.push_back(a);array.push_back(b);cout<<array.size()<<endl;cout<<array[0].size()<<endl;cout<<array[1][2]<<endl;}
(3)第3種方法: 使用vector < int* > v1;
#include <iostream>
#include <vector>
using namespace std;int main()
{ int out[3][2] = { 1, 2, 3, 4, 5, 6 }; vector <int*> v1; //相當于每一行是一個一維的數組,每個元素保存的是該數組的第一個元素地址// vector <vector<int>> v1; //這樣是錯誤的v1.push_back(out[0]); //壓入第一行元素 v1.push_back(out[1]); v1.push_back(out[2]); cout << v1[0][0] << endl; //1 cout << v1[0][1] << endl; //2 cout << v1[1][0] << endl; //3 cout << v1[1][1] << endl; //4 cout << v1[2][0] << endl; //5 cout << v1[2][1] << endl; //6 }