一維數組
數組的創建
數組是一種相同類型元素的集合
數組的創建方式
C99 中引入了變長數組的概念,變長數組支持數組的大小使用變量來指定
明顯這里的vs2019不支持變長數組
數組初始化和不完全初始化
第二個數組就是典型的不完全初始化,開辟了10個空間,只有第一個是1,剩下的就用0填充
這里的ch1和ch2看起來似乎一樣,但ch1只有 a b c, 后面的0是編譯器主動加上的;ch2是abc\0,\0的ASCII碼值也是0,所以后面也是6個0,但ch2本身就自帶了一個
這樣的代碼也是有問題的,這里只用了一個空字符串初始化,所以數組的長度是一個元素
一維數組的使用
一個數組初始化好后每個元素都有其下標,下標是從0開始的
一維數組在內存中的存儲
這里我們打印一下數組的每個元素的地址看看,%p是打印地址
我們發現每個相鄰的地址最后的數字就相差4,因為這是整形數組,而一個整型是4個字節
數組在內存重視連續存放的!
隨著數組下標的增長,地址也是由低到高變化的
數組開辟的空間也不宜太大
數組中的數據放在棧區
0和\0
二維數組
二維數組的創建
初始化
第一個參數是行數,第二個是列數
這個數組是怎么存放的呢?
其實是1234先把第一行放滿,5放在第二行,其余的位置都是0
還有另一種初始化方式
就是指定初始化位置
以及,對于二維數組,初始化時,可以省略行,不能省略列
二維數組的使用
我們嘗試一下一列一列打印
二維數組在內存中的存儲
試著打印一下地址看看
能發現他們似乎也是連續存放的
也能將它們理解為一個12元素的整型數組
數組越界
當我們訪問的空間超過數組申請的空間時,就造成了越界訪問
還有這樣
可能有人比較疑惑,為啥5會打印兩次呢?
第一次打印了5個,第二次還是從行的下標0位置處開始,5這個位置是數組第二行的第一個元素,所以還會被打印一次。
數組應用
冒泡排序
冒泡排序(Bubble Sort)是一種簡單直觀的排序算法
冒泡排序的核心思想是:
通過相鄰元素兩兩比較,把較大的元素“冒泡”到序列的一端,像水中的氣泡一樣逐步上升。
具體過程如下:
從頭到尾依次比較相鄰兩個元素,如果前一個比后一個大,就交換它們;
每完成一輪,最大的元素就被“冒泡”到了當前未排序部分的末尾;
然后對剩下的部分重復這一過程,直到整個序列有序。
比如排序 [5, 2, 4, 3, 1]
,第一輪結束后變成 [2, 4, 3, 1, 5]
,最大值 5 被放到了最后。之后對 [2, 4, 3, 1]
再次進行“冒泡”,直到全部排好序。
設有一個長度為 n
的數組,共需進行最多 n-1
輪“冒泡”:
第 1 輪:比較
n-1
次,把最大值移到末尾;第 2 輪:比較
n-2
次,把次大值移到倒數第二位;…
第
n-1
輪:只需比較 1 次。
基本理念就是數組中的元素兩兩相比較,隨后判斷是否交換位置,最終的目的是排成一個升序或降序數組
或者函數的形式
#include<stdio.h>
void bubble_sort(int arr[10])
{//求數組的元素個數int sz = sizeof(arr) / sizeof(arr[10]);//冒泡排序的趟數int i = 0;for (i = 0; i < sz - 1; i++){//一趟冒泡排序int j = 0;for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}int main()
{int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);//0 1 2 3 4 5 6 7 8 9//要對數組升序排序//冒泡排序bubble_sort(arr);//打印for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}
但結果好像不對誒~
原來上面數組名傳參的時候傳遞的只是數組首元素的地址,形參就是指針變量來接收,并沒有把整個數組傳上去。(這叫做數組名的降級)
上面sz就是1了,所以數組才會沒變化
這時我們只需要在main函數里先把sz計算好,然后傳給排序函數就行
#include<stdio.h>
void bubble_sort(int arr[10],int sz)
{//冒泡排序的趟數int i = 0;for (i = 0; i < sz - 1; i++){//一趟冒泡排序int j = 0;for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}int main()
{int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);//0 1 2 3 4 5 6 7 8 9//要對數組升序排序//冒泡排序bubble_sort(arr,sizeof(arr)/sizeof(arr[0]));//打印for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}
看一下這段代碼
運行結果是兩邊都相等!
這里剛好也得出了
當p指向數組的第一個元素時,p+i就指向數組第i個元素
p里存放著數組首元素的地址,所以p和arr可以相互替換,下面這些效果也相等
還有加法交換律能得出的結論
前面講了數組名是數組首元素地址,但存在兩個例外
sizeof(數組名),數組名表示整個數組,計算的是整個數組的大小,單位是字節
&數組名,數組名表示整個數組,取出的是整個數組的地址
看看這個,前面兩個+1后跳過了一個整型元素,地址都是+4,而第三個+1后跳過了整個數組,地址變化了40個字節