本篇前言
陣列就是一組相同型別元素的集合,通過陣列我們可以更為方便快捷的存盤和訪問資料,理論上來說C語言可以構造n維陣列,但是由于一維陣列和二維陣列使用更加頻繁,所以本篇著重講解一維陣列與二維陣列,多維陣列僅作了解,
文章目錄
- 一維陣列
- 創建一維陣列
- 一維整型陣列初始化
- 一維字符型陣列初始化
- 一維陣列的使用與記憶體中的存盤
- 二維陣列
- 創建二維陣列
- 二維陣列初始化
- 二維陣列的使用與記憶體中的存盤
- 多維陣列
- 陣列名到底是什么?
- 陣列名表示整個陣列
- 陣列名表示陣列首元素地址
一維陣列
存盤一個數或字符我們只需要定義一個變數,那存盤100個數或字符呢?方便快捷的存盤和訪問大量的資料,這就是陣列存在的意義,
創建一維陣列
語法:
陣列元素型別 陣列名 [整型常量運算式]
陣列元素型別指的是陣列中所有元素的資料型別,陣列名是陣列的名稱,方括號中的常量運算式的值代表陣列的元素個數(VS2019編譯環境下必須是常量運算式,DevC++編譯器支持C99語法,C99中有變長陣列的概念,允許使用變數運算式,所以小伙伴在devC++中使用變數定義陣列大小不會報錯,為了增加程式的容錯率建議仍使用常量運算式),
一維整型陣列初始化
創建變數時就對變數進行賦值的操作叫做初始化,單純的創建陣列就好比我們造出了一堆空盒子,接下來要做的是往盒子里放東西,
完全初始化:
完全初始化的意思是所有陣列元素都被初始化,即我們一上來就把盒子都放滿了
int a[5] = { 1,2,3,4,5 };

省略定義陣列元素個數則會自動完全初始化:
int a[] = { 1,2,3,4,5 };

不完全初始化:
指的是我們并沒有將所有元素都初始化
int a[5] = { 1,2,3 };

總結:一維整型陣列初始化的元素會從左到右被依次賦值,賦值數不能超過元素個數,未賦值元素默認為0,未標明元素個數的陣列則會自動完全初始化,
一維字符型陣列初始化
完全初始化:
char ch[5] = { 'h','e','l','l','o' };

char ch[5] = { 'h','e','l','l','\0' };

char ch[5] = { "hell" };

總結:字符型陣列可以一個元素一個元素的初始化也可以直接用字串初始化;區別是用字串初始化的時候會在末尾自動補"\0"作為字串結束的標志,
再看這三種寫法的字串長度(strlen)和字符陣列的大小(sizeof):
#include<stdio.h>
#include<string.h>
int main()
{
char ch1[5] = { 'h','e','l','l','o' };
char ch2[5] = { 'h','e','l','l','\0' };
char ch3[5] = { "hell" };
printf("%d ", strlen(ch1));
printf("%d ", strlen(ch2));
printf("%d\n", strlen(ch3));
printf("%d ", sizeof(ch1));
printf("%d ", sizeof(ch2));
printf("%d\n", sizeof(ch3));
return 0;
}

總結:列印字串和strlen函式計算字串長度時,默認"\0"是其結束的標志,ch1沒有"\0"作為字串的結束標志,ch2有,ch3由于是字串完全初始化自動補了"\0"所以也有,所以strlen函式下,ch1的字串長度就是隨機值,ch2和ch3的長度是4,由于這三個陣列都初始化了5個char型別的變數,一個char是一位元組,所以它們的陣列大小都是5,
如果省略陣列元素個數則會自動完全初始化,下圖的程式和上圖的程式功能完全一致:

不完全初始化:
char ch1[5] = { 'h','e','l','l'};

char ch2[5] = { 'h','e','l','\0' };

char ch3[5] = { "hel" };

總結:不完全初始化的字符型陣列會自動補"\0"
再看它們的字串長度(strlen)和字符陣列的大小(sizeof):
#include<stdio.h>
#include<string.h>
int main()
{
char ch1[5] = { 'h','e','l','l'};
char ch2[5] = { 'h','e','l','\0' };
char ch3[5] = { "hel" };
printf("%d ", strlen(ch1));
printf("%d ", strlen(ch2));
printf("%d\n", strlen(ch3));
printf("%d ", sizeof(ch1));
printf("%d ", sizeof(ch2));
printf("%d\n", sizeof(ch3));
return 0;
}

由于不完全初始化補了"\0",所以ch1的字串長度是4,ch2和ch3是3,陣列長度不變,仍然都是5,
整體總結:
1.不完全初始化會自動補齊元素,整型補0,字符型補\0
2.使用單個字符初始化不會補\0,使用字串初始化時會自動補\0
3.自動補\0或者0的操作僅在陣列空間未滿時進行,若空間已滿則不會進行
4.\0是字串結束的標志,strlen讀取的是\0之前的所有字符的個數
一維陣列的使用與記憶體中的存盤
訪問具體某個陣列元素是用下標實作的,陣列下標的值從0開始,比如a[0]代表的是陣列a的第一個元素
例子:
#include<stdio.h>
int main()
{
int a[5] = { 1,2,3,4,5 };
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", a[i]);
}
return 0;
}

一維陣列元素在記憶體中是連續存放的,隨著陣列下標的增長,地址由低到高變化:
例子:
#include<stdio.h>
int main()
{
int a[5] = { 1,2,3,4,5 };
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%p\n", &a[i]);
}
return 0;
}

這些地址是什么意思呢?地址下標是16進制,用0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F一共16個字符表示0~15的數字,經過計算可知,每個陣列元素的地址都差4,而且依次遞增,這個4是因為int型陣列每個陣列元素的大小是4位元組,如果是char型陣列,每個陣列的地址就差1位元組:
#include<stdio.h>
int main()
{
char a[5] = { 1,2,3,4,5 };
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%p\n", &a[i]);
}
return 0;
}

陣列元素在記憶體中是連續存放的,這個特性使得我們可以通過陣列首元素的地址來訪問整個陣列,也讓陣列的使用變得靈活起來
二維陣列
二維陣列,顧名思義是有兩個維度的陣列,

創建二維陣列
語法:
陣列元素型別 陣列名 [行數][列數];
int a[3][4];
char ch[3][4];
二維陣列初始化
僅介紹二維整型陣列的初始化:
1.順序初始化
int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };

int a[3][4] = {1,2,3,4,5,6,7,8,9};

陣列會從第一行開始一行一行的順序填入元素,缺位補0(字符補\0),
2.逐行初始化
int a[3][4] = { {1,2},{3,4,5},{6,7,8,9} };

每個子大括號表示一行的元素,缺位補0(字符補\0)
3.省略行數的初始化
C語言規定:二維陣列初始化可以省略行數,不能省略列數
int a[][4] = { {1,2},{3,4,5},{6,7,8,9} };

二維陣列的使用與記憶體中的存盤
二維陣列同樣用下標訪問,下標同樣從0開始,前一個下標是行下標,后一個下標是列下標,

#include<stdio.h>
int main()
{
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
printf("%-2d ", a[i][j]);
printf("\n");
}
return 0;
}

二維陣列在記憶體中的存盤也是連續存放的

#include<stdio.h>
int main()
{
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
printf("%p\n", &a[i][j]);
}
return 0;
}

多維陣列
我們可以將陣列的下標看成坐標,那么一維陣列就是一個離散的數軸,二維陣列就是一個離散的平面直角坐標系,那三維陣列其實就是一個離散的空間直角坐標系,n維陣列就是一個離散的n維空間

n維陣列其實就是n個一維陣列相嵌套:n維陣列是由若干n-1維陣列組成的,每個n-1維陣列是由若干n-2維陣列組成的…一直到每個2維陣列是由若干一維陣列組成的,
大家理解概念就好,用的不多不細說,
陣列名到底是什么?
除了定義陣列的時候使用陣列名,其他時候程式中出現陣列名的意義到底是什么?
陣列名表示整個陣列
只有兩個特殊情況下陣列名表示整個陣列:
1.sizeof計算整個陣列大小時:
#include<stdio.h>
int main()
{
int arr[10];
printf("%d", sizeof(arr));
return 0;
}

此時arr表示整個陣列,sizeof計算的是整個陣列的大小
2.取地址符+陣列名時:
#include<stdio.h>
int main()
{
int arr[10];
printf("%p", &arr);
return 0;
}

此時取出的也是整個陣列的地址,這個地址和陣列首元素的地址的值是相同的,但是它代表的是陣列的地址而不是陣列首元素的地址,值相同,含義不同,
陣列名表示陣列首元素地址
除了上面所說的兩種情況以外,其他所有情況下的陣列名均表示陣列首元素的地址,(我在【C語言從青銅到王者】第二篇·詳解函式中的傳址呼叫中也說了這一點)
給出一些例子佐證:



轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/280946.html
標籤:其他
