## 一.數組
+ 用來存放許多相同類型的數據,如一個班有很多的學生。
+ 無論它是一維還是多維,它都占用連續的空間。
## 二.一維數組
#### 1.定義和初始化
**基本格式**
```c
//數組長度必須是一個常量
數據類型 標識符[數組長度] = {初始值,初始值,...};
```
> 這個[數組長度]只是個修飾符,而不是類型的一部分。
**只定義但不初始化**
這時數組中每個元素的初值都是不確定的。如果是靜態的,則每個元素的初值為0。
```c
int a[10];
```
**定義并初始化**
```c
//初始化全部元素
int a1[5] = {1,2,3,4,5};
//初始化前3個元素,后面兩個元素則被編譯器初始化為0.
int a2[5] = {1,2,3};
//下面這句話也是對的,一維的長度可省,編譯器會自動判斷長度。省掉后數組必須初始化,不然編譯器咋知道你要多大的空間。
int a3[] = {1,2,3};
//下面這句話是錯的哎
int a4[1] = {1,2,3};
```
#### 2.訪問數組
**訪問和修改數組元素**
用數組名+下標訪問和修改即可。
**注意,編譯器不會檢查數組越界。**
```c
a1[1] = 100;
```
#### 3.數組名稱的含義
+ 它是數組類型,不是指針類型。可以 `sizeof` 數組名試試。
+ **萬惡之源** 大多數用到數組名的地方,編譯器會自動將其轉換為指向數組第一個元素的指針右值。除了用 `sizeof` 運算符、`typeid` 運算符、取地址運算符 `&` 訪問數組,或用數組初始化引用。
**不可以對數組整體賦值** 你能對一個右值賦值嘛?
此外,也不可以用一個數組去初始化另一個數組。
> 需要注意的是,數組是 **可復制的** 。但只是數組到指針右值的轉換導致不能直接使用 `=` 進行賦值或用另一個數組來初始化。
#### 4.向函數傳遞一維數組
+ 如果形參是數組,則編譯器會自動替換成指針。
+ 所以形參中聲不聲明一維數組的大小是無所謂的。
```c
void sort(int arr[],int size);
//編譯器替換后,arr就是指針
void sort(int *arr,int size);
```
> 注意,這個不是轉換,而是直接替換。轉換會生成一個新的值,而不改變自身值,而替換,就很簡單粗暴了。
```c
int i = 2;
double d = i;//i的值會拷貝一份,轉換成double型,但是操作完后i的值仍是int。
```
#### 5.向函數返回一維數組
這是不允許的操作~~
下面這個寫法也是錯的。
函數返回的時候a已經沒了,返回的地址就不知道指向什么地方了。
```c
int* return_a_array()
{
int a[10];
return a;
}
```
## 三.二維數組
#### 1.定義和初始化
**基本格式**
```c
//數組長度必須是一個常量
數據類型 標識符[一維的長度][二維的長度] = 初始化列表;
```
跟上面的一維數組的定義和初始化差不多的,你可以只定義而不初始化,也可以定義的時候初始化。
對于初始化語句,你可以進行分開賦值,也可以進行連續賦值:
```c
//連續賦值
int arr1[2][3] = {1,2,3,4,5,6};//arr1:{{1,2,3},{4,5,6}}
int arr2[2][3] = {1,2};//arr2:{{1,2,0},{0,0,0}}
//分開賦值
int arr3[2][3] = {{1,2,3},{4,5,6}};//arr3:{{1,2,3},{4,5,6}}
int arr4[2][3] = {{1,2},{4,5}};//arr4:{{1,2,0},{4,5,0}}
```
在多維數組的定義和初始化中,只能省掉一維的長度。
```c
//得到 int[2][3]
int arr[][3] = {1,2,3,4,5,6};
```
#### 2.訪問數組
**訪問和修改數組元素**
用數組名+下標訪問和修改即可。
```c
arr[1][1] = 100;
```
#### 3.向函數傳遞二維數組
+ 如果形參是數組,則編譯器會自動替換成指針。
+ 因為這個指針是指向數組的,因此二維部分需要指明大小。
```c
void output(int arr[][20],int size);
//編譯器替換后,arr就是指針
void output(int (*arr)[20],int size);
```
#### 3.二維數組各維度的類型
二維數組可以看成 一個每個元素都是數組類型的一維數組。
例如,
```c
int a[5][10];
```
`a` 是一個二維數組,類型為 `int[5][10]`。
`a[0]` 是一個一維數組,類型為 `int[10]`。
`a[0][0]` 則是整型。
## 三.數組與指針的關系
1. 在大多數表達式下,數組名自動轉換成指向數組首元素的指針。
2. **[11+]\[$]** 使用數組初始化一個 `auto`關鍵字定義的變量時,得到一個指向數組首元素的指針。
3. **[11+]\[$]** 獲取數組的首尾地址
```c++
//請勿使用VC6.0等古董編譯器運行此例
int score[] = {56, 87, 64, 98, 74, 56, 78, 69, 88, 99};
int *start = std::begin(score);//指向第一個元素
int *back = std::end(score);//指向末尾元素的下一個元素
```
- 閱讀說明
- 1.1 概述
- C++基礎
- 1.2 變量與常量
- 1.2.1 變量
- 1.2.2 字面值常量
- 字符型常量
- 數值型常量
- 1.2.3 cv限定符
- 1.3 作用域
- 1.3.1 標識符
- 1.3.2 *命名空間
- 1.3.3 作用域
- 1.3.4 可見性
- 1.4 數據類型
- 1.4.1 概述
- 1.4.2 處理類型
- 類型別名
- * auto說明符
- * decltype說明符
- 1.4.3 數組
- 1.4.4 指針
- 1.4.5 引用
- 1.5 表達式
- 1.5.1 概述
- 1.5.2 值的類別
- 1.5.3 *初始化
- 1.5.4 運算符
- 算術運算符
- 邏輯和關系運算符
- 賦值運算符
- 遞增遞減運算符
- 成員訪問運算符
- 位運算符
- 其他運算符
- 1.5.5 *常量表達式
- 1.5.6 類型轉換
- 第2章 面向過程編程
- 2.1 流程語句
- 2.1.1 條件語句
- 2.1.2 循環語句
- 2.1.3 跳轉語句
- 2.1.4 *異常處理
- 2.2 函數
- 2.2.1 概述
- 2.2.2 函數參數
- 2.2.3 內置函數
- 2.2.4 函數重載
- 2.2.5 * 匿名函數
- 2.3 存儲和生命期
- 2.3.1 生命周期與存儲區域
- 2.3.2 動態內存
- 2.4 *預處理命令
- 第3章 面向對象編程
- 3.1 概述
- 3.2 類和對象
- 3.3 成員
- 3.3.1 訪問限制
- 3.3.2 常成員
- 3.3.3 靜態成員
- 3.3.4 成員指針
- 3.3.5 this指針
- 3.4 特殊的成員函數
- 3.4.1 概述
- 3.4.2 構造函數
- 3.4.3 析構函數
- 3.4.4 拷貝語義
- 3.4.5 * 移動語義
- 3.5 友元
- 3.6 運算符重載與類型轉換
- 3.6.1 概述
- 3.6.2 重載方法
- 3.6.3 類型轉換
- 3.7 繼承與多態性
- 3.7.1 概述
- 3.7.2 派生類
- 3.7.3 子類型
- 3.7.4 虛基類
- 3.7.5 虛函數
- 3.7.6 抽象類
- 3.8 模板與泛型
- 3.8.1 概述
- 3.8.2 模板類型
- 3.8.3 *模板參數
- 3.8.4 *模板編譯
- 3.8.5 *模板推斷
- 3.8.6 *實例化與特例化
- 第4章 C++標準庫
- 4.1 概述
- 4.2 輸入輸出流
- 4.2.1 概述
- 4.2.2 *流的狀態
- 4.2.3 *常用流
- 4.2.4 *格式化I/O
- 4.2.5 *低級I/O
- 4.2.6 *隨機訪問
- 4.3 *C輸入輸出
- 4.3.1 *字符輸入輸出
- 4.3.2 *格式化輸入輸出
- 4.4 * 容器
- 4.4.1 * 概述
- 4.4.2 * 基本操作
- 4.4.3 * 順序容器
- 4.4.4 * 迭代器
- 4.4.5 * 容器適配器
- 4.5 * 泛型算法
- 4.6 * 內存管理
- 4.6.1 * 自動指針
- 4.7 * 其他設施