當前位置:網站首頁>C語言 數組(一維數組 · 二維數組)
C語言 數組(一維數組 · 二維數組)
2022-05-14 07:32:09【牧瀬 紅莉棲】
C語言的數組知識
一、一維數組的創建和初始化
1.1 數組的創建:
數組是一組相同類型元素的集合。數組的創建方式:
type_t arr_name [const_n];
// type_t 指數組的元素類型
// arr_name 數組的名稱
// const_n 這是一個常量錶達式,用來指定數組的大小
數組創建的實例:
int arr01[10];
int i = 10;
int arr02[i]; //數組是否可以正常創建?
float arr03[3];
double a04[50];
注:數組創建的時候,[ ]中要給一個常量才可以,不能使用變量。
1.2 數組的初始化:
數組的初始化是指,在創建數組的時候,給數組的內容同時賦值一些合理初始化值。
int arr1[10] = {
1,2,3 };
int arr2[] = {
1,2,3,4 };
char arr3[3] = {
'a',98,'c' };
char arr4[] = {
'a','b','c' };
char arr5[] = "abcdef";
數組創建的時候,不指定數組大小就可以初始化,數組的元素個數根據初始化的內容來確定。
但是對於下面的代碼,要區分內存中如何分配。
char ch1[5] = {
'b','i','t' };
char ch2[] = {
'b','i','t' };
char ch3[] = "bit";
printf("%d\n", strlen(ch1));
printf("%d\n", strlen(ch2));
printf("%d\n", strlen(ch3));
如圖,strlen( ) 函數只是計算字符串大小,初始化只有三個字符,為什麼中間那個輸出15呢?
我們開啟調試查看一下三個 ch 字符數組的情况。
- 第一個 ch 字符數組,初始化五個空間,使用三個後,其他沒有使用的空間默認 ’ \0 ’ 結束標志,所以計算數組元素個數,顯示為3。
- 第二個 ch 字符數組,沒有初始化空間,那就根據數組元素個數分配空間。定義三個字符元素,但是沒有給出 ’ \0 ’ 結束標志,所以數組計算長度沒有及時結束,一直在內存中遇到某個 ’ \0 ’ ,程序才結束。
- 第三個 ch 字符串數組,同樣沒有初始化空間,但是這裏提供的是字符串數組,字符串末尾自帶 ’ \0 ’ ,所以正常結束,顯示為3。
二、一維數組的使用
對於數組的使用,我們之前介紹了一個操作符:[ ] ,下標引用操作符。它其實就是數組訪問的操作符。
//數組的使用
int arr[10] = {
0 }; //數組不完全初始化
//計算數組元素個數
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
//循環賦值
for (i = 0; i < 10; i++) {
arr[i] = i;
}
//輸出數組的內容
for (i = 0; i < 10; i++) {
printf("%d", arr[i]);
}
小結:
- 數組是使用下標來訪問的,下標是從0開始。
- 數組的大小可以通過計算獲得。
三、 一維數組在內容中的存儲
接下來我們探討下數組在內容中的存儲。
//數組在內存中的存儲
int i = 0;
int arr[10] = {
0 };
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
printf("&arr[%d] = %p\n", i, &arr[i]);
}
輸出結果如下:
仔細觀察輸出結果,我們會發現:
- 數組的每個元素間距都是相差4,這是因為我們定義的是int類型的數組。
- 隨著數組下標的增長,元素的地址,也會有規律的遞增。
由此可以得出結論:數組在內存中是連續存放的。
四、二維數組的創建和初始化
4.1 二維數組的創建
二維數組是兩個[ ],第一個[ ]控制行數,第二個[ ]控制列數(每行上有幾個元素)。
可以在{ }裏面套個{ },用來初始化每列上的元素。
可以省略第一個[ ],這樣程序會根據第二個[ ]判斷每行有幾個元素,然後進行初始化。
但是第二個[ ]不能省略。
//二維數組的初始化
int arr1[3][4] = {
1,2,3,4 };
int arr2[3][4] = {
{
1,2},{
3,4} };
int arr3[][4] = {
1,2,3,4 };
int arr4[][4] = {
{
1,2},{
3,4} };
4.2 二維數組的使用
二維數組的使用也是通過下標的方式。
int arr1[3][4] = {
0 };
int i = 0;
//外層for,第一個[]控制行數
for (i = 0; i < 3; i++) {
int j = 0;
//內層for,第二個[]控制列數
for (j = 0; j < 4; j++) {
//二維數組賦值
arr1[i][j] = i * 4 + j;
}
}
//輸出二維數組
for (i = 0; i < 3; i++) {
int j = 0;
for (j = 0; j < 4; j++) {
printf("arr1[%d][%d] = %d\n", i, j, arr1[i][j]);
}
}
五、 二維數組在內存中的存儲
像一維數組一樣,我們嘗試打印二維數組的每個元素。
//二維數組在內層中的存儲
int arr[3][4];
int i = 0;
for (i = 0; i < 3; i++) {
int j = 0;
for (j = 0; j < 4; j++) {
printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
}
}
我們取二維數組地址輸出,發現二維數組在內存中存儲的地址也是連續的。
所以二維數組也是線性存儲的,不是像矩陣那樣有行有列。
六、數組作為函數參數
我們在編寫代碼的時候,有時候會把數組作為參數傳遞給函數,例如:我們現在要實現一個冒泡排序的函數,能把一個整型數組排序。
冒泡排序:把一個亂序的數組進行排序。
將數組的第一個元素和第二個元素對比,如果第一個元素比第二個大,就交換比特置;然後第二個比特置的元素和第三個比特置的元素比較,前一個大就交換比特置…一直到走完這一趟,會發現數組最後一個元素是數組中最大的元素。接下來就是下一趟比較,重複上述操作…
動圖演示:
了解了冒泡排序,讓我們回到數組作為函數參數,設計個能完成冒泡排序的函數。
6.1 冒泡排序函數的錯誤設計
//方法1:
#include <stdio.h>
void bubble_sort(int arr[])
{
int sz = sizeof(arr)/sizeof(arr[0]);//這樣對嗎?
int i = 0;
for(i=0; i<sz-1; i++)
{
int j = 0;
for(j=0; j<sz-i-1; j++)
{
if(arr[j] > arr[j+1])
{
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
int main()
{
int arr[] = {
3,1,7,5,8,9,0,2,4,6};
bubble_sort(arr);//是否可以正常排序?
for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
return 0;
}
方法1,出現問題。調式我們發現,bubble_sort函數內部的sz是1。就是沒有成功計算出數組大小,導致函數不能完成排序。
難道數組作為函數參數的時候,不是把整個數組傳遞過去?
6.2 數組名是什麼?
讓我們取數組名的地址看一下。
int arr[10] = {
1,2,3,4,5 };
printf("%p\n", arr);
printf("%p\n", &arr[0]);
printf("%d\n", *arr);
看下輸出結果,我們可以發現,數組名和數組首元素地址是一樣的。數組名就是數組首元素地址
但是若數組名是首元素地址,那麼我們計算一下數組名。
int arr[10] = {
1,2,3,4,5 };
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr[0]));
為什麼輸出的結果是:40和4?不是說兩個的地址是一樣的嗎?
因為==數組名是數組首元素的地址。==有兩個例外:
- sizeof(數組名),計算整個數組的大小,sizeof內部單獨放一個數組名,數組名錶示整個數組。
- 取地址符號&。&數組名的組合,取出的是數組的地址。&數組名,數組名錶示整個數組。
除了這兩種情况之外,所有的數組名都錶示數組首元素的地址。
6.3 冒泡排序函數的正確設計
之前我們簡單的把數組名作為函數參數傳遞過去,實際上只是把數組首元素地址傳遞過去而已。
所以之後我們在sizeof()計算數組大小
int sz = sizeof(arr) / sizeof(arr[0])
只是把傳遞過來的數組(實際上是數組首元素地址),除於數組首元素地址。
自己除於自己,結果sz等於1.
//冒泡排序
//bubble_sort方法
void bubble_sort(int arr[], int sz) {
int i = 0;
for (i = 0; i < sz - 1; i++) {
int j = 0;
for (j = 0; j < sz - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
//main方法
int i = 0;
int arr[] = {
3,1,7,5,8,9,0,2,4,6 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);
for (i = 0; i < sz; i++) {
printf("%d\n", arr[i]);
}
版權聲明
本文為[牧瀬 紅莉棲]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/134/202205140613192325.html
邊欄推薦
猜你喜歡
隨機推薦
- 【服務器數據恢複】硬盤壞道和不穩定扇區導致服務器崩潰的數據恢複案例
- 性能測試報告編寫技巧
- ASP.NET對Cookie的操作方法有哪些
- SAP UI5 應用開發教程之八十七 - 如何讓 SAP UI5 Mock 服務器支持自定義 url 參數試讀版
- Redis基礎之溫故
- 神經網絡中的反向傳播&&參數更新
- 深度學習基礎知識點(一)CNN卷積神經網絡——1.卷積方面的原理
- 從PlatEMO中提取真實PF前沿
- G020-OP-INS-RHEL-02 RedHat OpenStack 發放雲主機(命令行)
- 解决報錯: AttributeError: module ‘distutils‘ has no attribute ‘version‘,親測有效
- 一文了解字節跳動如何解决 SLA 治理難題
- openstack底層提取所有虛擬機IP和其uuid、openstack底層提取所有虛擬機的所在宿主機
- 安裝mysql-community-server報錯缺少libaio依賴
- gin框架疑問, 為什麼不使用 *RouterGroup
- Redis分頁
- 【數據庫系統工程師】6.4數據倉庫和數據挖掘基礎知識
- PyTorch分類識別例子
- npx hardhat verify YOUR_CONTRACT_ADDRESS --network rinkeby
- 番外篇-穀粒商城的數據庫錶結構設計SQL語句
- 19. 删除鏈錶的倒數第 N 個結點
- c# 獲取枚舉描述的擴展方法
- 應如何認定解除合同通知的效力?
- 遊戲行業實戰案例5:玩家在線分布
- 【LeetCode】Day59-醜數 & 不同的二叉搜索樹
- CTFSHOW MISC入門
- 【國產免費】分布式作業批量處理平臺TASKCTL驗證的不同方式
- 數學建模學習(66):支持向量機 (SVM)案例實戰
- Thanos Sidecar組件
- Meta AI 宣布對人腦和語言處理進行長期研究
- 檢討書範文生成微信小程序工具源碼-支持流量主
- 元組類型(C# 參考)
- PTC:元宇宙引發醫療設備研發重大變革
- 面試題 01.05. 一次編輯 / 劍指 Offer II 041. 滑動窗口的平均值
- 華為機試第十一題:HJ11 數字顛倒
- Pascal VOC2012數據集
- unzip命令
- flink(scala版)學習一之常用的source
- [電路]7-實際電源模型和等效變換
- Go語言type自定義類型哦
- Pytorch和GPU有關操作(CUDA)