C語言第 9 天學習筆記:數組(二維數組與字符數組)

C語言第09天學習筆記:數組(二維數組與字符數組)

內容提要

  • 數組
    • 二維數組
    • 字符數組

二維數組

定義

二維數組本質上是一個行列式組合,由行和列兩部分組成,屬于多維數組,通過行和列解讀(先行后列)。

二維數組可被視為一個特殊的一維數組,即當一個數組中的每一個元素是一維數組的時候,這個數組就是二維數組。

語法

數據類型 數組名[行容量][列容量];
  • 行容量:外層數組的數組容量
  • 列容量:內層數組的數組容量

說明

  • 二維數組在初始化的時候,可以省略行數,系統會通過初始化后的數據自動推斷行數。
  • 二維數組和一維數組一樣,也可以部分初始化,未初始化的元素使用0。
  • 二維數組在初始化的時候,不能省略列數,否則編譯報錯。

舉例

int arr[3][3] = {{11,12,13},{21,22,23},{31,32,33}}; // 正確
int arr[][3] = {{11,12,13},{21,22,23},{31,32,33}}; // 正確,可省略行容量,推薦int arr[3][3] = {{11,12},{21,22,23},{31}}; // 正確,未初始化部分補0
int arr[3][3] = {{11,12,0},{21,22,23},{31,0,0}}; // 正確,支持部分初始化
int arr[3][3] = {0}; // 正確,所有位置使用0補齊,推薦
int arr[3][3] = {}; // 正確,所有位置使用0補齊
int arr[3][3] = {11}; // 正確,除了0行0列是11外,其他都用0補齊int arr[][] = {{11,12,13},{21,22,23},{31,32,33}}; // 錯誤,不能省略列容量
int arr[3][] = {{11,12,13},{21,22,23},{31,32,33}}; // 錯誤,不能省略列容量int arr[][3] = {11,12,13,21,22,23,31,32,33}; // 正確,{}中不一定嵌套
int arr[][3] = {11,12,13,21}; // 正確,{}中不一定嵌套

內存存儲

在C語言中,二維數組在計算機的存儲順序是按行進行的,即第一維(行)下標變化慢,第二維(列)下標變化快。

例如:
在這里插入圖片描述

注意:地址這里只是為了區分,實際的地址表示為十六進制。

應用場合

主要應用于對行列有要求的情況,例如:

  • double scores[35] = {..}; :一維數組初始化,存放1個班所有學生的成績
  • double scores[5][40] = {{..}..} :二維數組初始化,存放5個班的學生成績,每個班最多40人
  • double scores[6][10][40] = {{{..}..}..} :三維數組初始化,存放6個校區、每校區最多10個班,每班最多40人

特殊寫法

  • 下標可以是整型表達式,如 a[2-1][2*2-1] 等價于 a[1][3]

  • 下標可以是已經有值的變量或者數組元素,如 a[2*x-1][b[3][1]][] 中最終需要的是一個大于0的整數

  • 數組元素可以出現在表達式中,如 b[1][2] = a[2][3]/2

  • 演示:

    數組:arr列-0列-1列-2舉例說明
    行-0111213arr[0][1]數組arr的0行1列對應的元素
    行-1212223arr[1][2]數組arr的1行2列對應的元素

注意:使用數組元素的下標應在已定義數組的大小范圍內;應注意區別定義數組大小和引用數組元素的區別。

初始化

  1. 分行給二維數組賦初值
    int arr[3][4] = {{11,12,13,14},{21,22,23,24},{31,32,33,34}};
    
  2. 可將所有數據寫在一個{}內,按照排列順序賦值
    int arr[3][4] = {11,12,13,14,21,22,23,24,31,32,33,34};
    
  3. 可對部分元素賦初值,其余未初始化部分自動填充0
    int arr[3][4] = {{11},{21,22},{31,32,33}};
    
  4. 若對全部元素賦初值,自定義數組時可以省略第一維數組容量(行容量),第二維數組容量(列容量)必須指明
    int arr[][4] = {{11,12,13,14},{21,22,23,24},{31,32,33,34}};
    int arr[][4] = {11,12,13,14,21,22,23,24,31,32,33,34};
    
  5. 在分行賦初值時,也可以省略第1維的長度(行容量)
    int arr[][4] = {{11,12,13},{0},{0,10}};
    

案例

案例1:二維數組的遍歷

分析:

  • 二維數組本質上屬于行列式,遍歷的時候需要借助于嵌套的for循環,外層for負責行的遍歷,內層for負責列的遍歷。
  • 行和列的大小計算:
// 計算行的大小
int row_length = sizeof(數組名) / sizeof(數組名[行下標0]);
// 計算列的大小(每一行的列數是相同)
int col_length = sizeof(數組名[行下標0]) / sizeof(數組名[行下標0][列下標0]);```代碼:
```c
#include <stdio.h>int main(int argc,char *argv[])
{// 創建一個二維數組int arr[][3] = {{11},{21,22},{31,32,33}};// 獲取行和列的大小int row_len = sizeof(arr) / sizeof(arr[0]);// 外層數組大小int col_len = sizeof(arr[0]) / sizeof(arr[0][0]);// 內層數組大小// 遍歷數組// 外層循環:遍歷行for (int i = 0; i < row_len; i++){// 內層循環:遍歷列for (int j = 0; j < col_len; j++){// 輸出元素printf("%-4d", arr[i][j]);}printf("\n");}return 0;
}

運行結果:

11  0   0
21  22  0
31  32  33
案例2:矩陣的轉置

分析:所謂的轉置,就是原本的列變行,行變列。

例如,2行3列矩陣轉置為3行2列矩陣:

111213
212223

轉置后:

1121
1222
1323

代碼:

#include <stdio.h>#define ROW 2
#define COL 3int main(int argc,char *argv[])
{// 定義循環變量int i,j;// 準備2個數組,用來存放轉置前后的數列int arr_before[ROW][COL] = {11,12,13,21,22,23};int arr_after[COL][ROW] = {0};// 計算數組的大小int arr_before_row = sizeof(arr_before) / sizeof(arr_before[0]);int arr_before_col = sizeof(arr_before[0]) / sizeof(arr_before[0][0]);int arr_after_row = sizeof(arr_after) / sizeof(arr_after[0]);int arr_after_col = sizeof(arr_after[0]) / sizeof(arr_after[0][0]);// 循環遍歷二維數組printf("\n轉置前:\n");for (i = 0; i < arr_before_row; i++){for (j = 0; j < arr_before_col; j++){// 打印轉置前的數據printf("%-4d",arr_before[i][j]);// 轉置:行變列,列變行arr_after[j][i] = arr_before[i][j];}printf("\n");}printf("\n");printf("轉置后:\n");for (i = 0; i < arr_after_row; i++){for (j = 0; j < arr_after_col; j++){printf("%-4d",arr_after[i][j]);}printf("\n");}printf("\n");return 0;
}

字符數組

概念

元素類型為char(字符型)的數組叫做字符數組,往往用來存儲字符串數據。C語言中的字符是字節字符(1字符=1字節,1char=8bit)。

硬件中存放數據以bit(位)為單位,系統對于內存的操作以char(字節)為單位,系統為內存以1個字節為單位進行編號。

實驗:

char a = 'A'; // 正確
char b = '1'; // 正確,ASCII碼:49
char c = 1; // 正確,ASCII碼:1
char d = '\n'; // 正確,只要其對應的ASCII碼的范圍在0~127之間,都屬于字符
char e = "A"; // 錯誤,雙引號括起來的內容叫做字符串常量
char f = '馮'; // 錯誤,中文字符不在0~127這個范圍內

語法

  • 一維數組:char 數組名[數組容量];
  • 二維數組:char 數組名[行容量][列容量];

字符數組的語法與之前所學的一維數組和二維數組的語法類似,只不過數據類型是char

注意:如果char數組初始化的時候,沒有完全初始化值,未初始化部分使用\0\0對應的ASCII值是0)進行填充,\0無法通過printf等打印輸出到控制臺。

例如:

char c[8] = {'h','e','l','l','o'}; // 等價于 char c[8] = {'h','e','l','l','o','\0','\0','\0'};

案例

案例1:輸出一個字符序列(I LOVE YOU)

代碼:

#include <stdio.h>int main(int argc,char *argv[])
{// 創建一個數組,用來存儲I LOVE YOU,空格' '也是字符,對應的ASCII為32char arr[] = {'I',' ','L','O','V','E',32,'Y','O','U'};// 計算數組的大小int len = sizeof(arr) / sizeof(arr[0]);// 遍歷數組for (int i = 0; i < len; i ++)printf("%c",arr[i]);printf("\n");return 0;
}
案例2:輸出一個用字符*組成的空菱形圖案

代碼:

#include <stdio.h>int main(int argc,char *argv[])
{// 創建一個二維數組,存放菱形char arr[5][5] = {{' ', ' ', '*', ' ', ' '},{' ', '*', ' ', '*', ' '},{'*', ' ', ' ', ' ', '*'},{' ', '*', ' ', '*', ' '},{' ', ' ', '*', ' ', ' '}};// 計算行和列的大小int row_len = sizeof(arr) / sizeof(arr[0]);int col_len = sizeof(arr[0]) / sizeof(arr[0][0]);// 遍歷數組for (int i = 0; i < row_len; i++){for (int j = 0; j < col_len; j++)printf("%c",arr[i][j]);printf("\n");}printf("\n");return 0;
}

注意

  • 如果定義時,不初始化,元素值不確定(局部作用域)
    char arr1[2]; // 此時,這個數組中元素的值是隨機值
    char arr2[3] = {'a','b','c'}; // 完全初始化
    char arr3[3] = {}; // 此時所有的元素使用 \0 填充
    char arr4[3] = {0}; // 此時所有的元素使用 \0 填充
    
  • 如果提供的字符個數大于數組長度,則按照語法錯誤處理(會報警告,但是能編譯通過);如果字符個數小于數組長度,后面的元素自動補\0
    char arr1[2] = {'h','e','e'}; // 編譯通過,但是會報警告(warning),不建議寫,實際存放的是he
    char arr2[3] = {'a'}; // 正確寫法,部分初始化,未初始化部分補 \0
    
  • 如果提供的字符個數與數組長度相同,可以省略數組長度,系統會自動確定元素的個數,適合字符較多時
    char arr1[] = {'b','u'}; // 正確,根據初始化元素,由系統自動計算元素個數
    

字符串結束標志

  • C語言規定,字符串常量以字符\0作為結束標志。
  • 編譯系統對字符串常量自動加一個\0作為結束標志,例如 char *name = "tom",實際存儲為{'t','o','m','\0'}
  • 程序中往往通過判斷\0來檢測字符串是否結束,例如 while(arr[i] != '\0') {..}
  • \0的ASCII碼是0,不是一個可顯示可輸出的字符,是“空操作符”,僅僅用作一個工程判別的標志或者在數組中占位。

例如:

char a[] = {'h','i'}; // 輸出:hi
char a[] = {'h','i','\0'}; // 輸出:hi
char c[] = "hello"; // 輸出:hello,實際存儲:hello\0,將字符串常量賦值給字符數組

字符數組的多樣表示

char數組可以以數組的形式一個一個輸出每個字符,也可以以字符串的形式整體輸出。

演示:

#include <stdio.h>int main(int argc,char *argv[])
{// 字符串的第1種表示:char s1[] = {'h','e','l','l','o','w','o','r','l','d','\0'};// 字符個數:12// 字符串的第2種表示:char s2[] = {"hello world"};// ""包裹的內容是字符串常量,字符串常量默認末尾有一個\0,字符個數:12// 字符串的第3種表示:char s3[] = "hello world"; // 字符個數:12// 字符串的第1種輸出:// 計算字符串所占字節數printf("s1=%lu,s2=%lu,s3=%lu\n", sizeof(s1), sizeof(s2), sizeof(s3)); // s1=12,s2=12,s3=12// 計算數組大小int len = sizeof(s3) / sizeof(s3[0]);// 遍歷for (int i = 0; i < len; i++){// 過濾\0if (s1[i] == 0 || s2[i] == '\0' || s3[i] == 0)continue;printf("%c,%c,%c\n", s1[i], s2[i], s3[i]);}printf("\n");// 字符串的第2種輸出:printf("%s,%s,%s\n",s1,s2,s3);printf("\n");return 0;
}

注意

  • 字符串的長度與字符數組的長度不一定相同。
    char name[] = "hello"; // 數組長度:6,字符串長度:5
    
  • 利用字符串常量可以對字符數組進行初始化,但不能用字符串常量對字符數組賦值。
    // 正確演示:利用字符串常量給字符數組初始化
    char arr1[] = "hello";// 錯誤演示:利用字符串常量給字符數組賦值
    char arr2[6];
    arr2 = "hello"; // 錯誤,數組名是常量,不能被賦值

一維數組練習題

  1. 鍵盤錄入一組數列,利用冒泡排序將數據由大到小排序
  2. 從鍵盤輸入年、月、日,計算并輸出該日是該年第幾天
  3. 鍵盤錄入一組數列,求最大數、最小數、均值
  4. 從鍵盤錄入一組數列,判斷是否是回文,舉例:12321,abba,121
  5. 用數組存儲10個整型數,通過鍵盤輸入一個數,找出該數在數組中的下標值
  6. 通過鍵盤輸入 10 個學員成績:
    1)輸出不及格學員的成績和下標。
    2)求最高分的下標值
    3)求最低成績的下標值
    4)求總成績及平均成績

二維數組練習題

  1. 一個二維數組賦了初值,用戶輸入一個數,在該二維數組中查找。找到則返回行列位置,沒找到則提示。
  2. 二維整型數組,求所有元素平均值,求每行最大值,求每列最小值。
  3. 在行列相等數組計算主對角線元素的和
  4. 計算一個矩陣下三角元素的和
  5. 電影院為了答謝影迷的支持,在某一排的某一列座位上放置了一個大禮包,放置禮物的位置具有這樣的規則(行和列的平方和為開店日期 512(5月12日)); 請設計程序找出大禮包的位置,(假定電影院有20排,每排25個座位)

字符數組練習題

  1. 編寫一個程序,讀取用戶輸入的字符串,并將其反轉輸出。
  2. 編寫一個程序,判斷用戶輸入的字符串是否為回文(即正反讀都一樣的字符串)。

思考題【選做】

  1. 求出一個矩陣的鞍點。鞍點的含義為行上最大同時列上也最大。

注::后續筆記將圍繞C語言知識展開,建議每日實操時長不少于3小時

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/916660.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/916660.shtml
英文地址,請注明出處:http://en.pswp.cn/news/916660.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用OpenCV做個圖片校正工具

昨天有位兄臺給我發了個文件&#xff0c;是下面這個樣子的&#xff1a;那一雙小腳既沒有裹成三寸金蓮&#xff0c;又沒有黑絲&#xff0c;這圖片肯定不符合我的要求。我要的是這個樣子的好不好&#xff1a;讓他拿掃描儀重新給我規規矩矩掃一個發過來&#xff1f;他要能用掃描儀…

《不只是接口:GraphQL與RESTful的本質差異》

RESTful API憑借其與HTTP協議的天然融合&#xff0c;以資源為核心的架構理念&#xff0c;在過去十余年里構建了Web數據交互的基本秩序&#xff1b;而GraphQL的出現&#xff0c;以“按需獲取”為核心的查詢模式&#xff0c;打破了傳統的請求-響應邏輯&#xff0c;重新定義了前端…

博士招生 | 香港大學 招收人工智能和網絡安全方向 博士生

學校簡介香港大學創立于 1911 年&#xff0c;是香港歷史最悠久的高等學府&#xff0c;QS 2025 世界排名第 17 位。計算機科學學科在 QS 2025 學科排名中位列全球第 31 位、亞洲第 5 位。計算機系&#xff08;Department of Computer Science&#xff09;下設系統、人工智能、數…

Linux知識回顧總結----基礎IO

目錄 1. 理解“文件” 1.1 文件的定義 2. 回顧 C 語言的文件操作 2.1 文件操作 2.2 實現cat 2.3 可以實現打印的幾種方式 3. 系統文件的IO 3.2 使用系統的接口 3.3 內部的實現 3.4 重定向 4. 文件系統的內核結構 5. 緩沖區 5.1 是什么 5.2 為什么 5.3 有什么 5.4 見見…

網絡:基礎概念

網絡&#xff1a;基礎概念 在計算機發展過程中&#xff0c;最開始每個計算機時相互獨立的&#xff0c;后來人們需要用計算機合作處理任務&#xff0c;這就牽扯到了數據交換&#xff0c;所以最開始的網絡就誕生了。一開始&#xff0c;網絡都是局域網LAN&#xff0c;后來技術成熟…

圖像識別邊緣算法

文章目錄1. 基本概念2. 邊緣檢測原理邊緣類型&#xff1a;3. 常見邊緣檢測算法3.1 Sobel算子3.2 Canny邊緣檢測3.3 Laplacian算子4. Canny邊緣檢測詳細流程流程圖示例&#xff1a;詳細步驟說明&#xff1a;5. 邊緣檢測算法比較6. 參數調優建議Canny邊緣檢測參數&#xff1a;Sob…

【Java Web實戰】從零到一打造企業級網上購書網站系統 | 完整開發實錄(終)

&#x1f9ea; 測試與質量保證 &#x1f50d; 全方位測試體系 我建立了企業級的全方位測試體系來確保系統質量&#xff1a; &#x1f9ea; 測試金字塔模型 #mermaid-svg-u4I8UuUAyxJVjcqs {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill…

QT開發---網絡編程下

HTTP協議 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;是互聯網上應用最為廣泛的協議之一&#xff0c;用于客戶端和服務器之間的通信。默認端口80&#xff0c;傳輸層使用的是TCP協議特點無連接&#xff1a;HTTP協議是無連接的&#xff…

mac 蘋果電腦 Intel 芯片(Mac X86) 安卓虛擬機 Android模擬器 的救命稻草(下載安裝指南)

引言&#xff1a; 還在為你的Intel芯片MacBook&#xff08;i5, i7, i9等&#xff09;找不到合適的安卓虛擬機而發愁嗎&#xff1f;隨著Apple Silicon (M1/M2/M3) 芯片的普及&#xff0c;大量優秀的安卓模擬器&#xff08;如Android Studio自帶的模擬器、網易MuMu等&#xff09;…

C語言:順序表(上)

C語言&#xff1a;順序表&#xff08;上&#xff09; 1.順序表的介紹 2.順序表的實現 1.順序表的介紹 線性表是n個具有相同特性的數據元素的有限序列。 線性表是一種在實際中廣泛使用的數據結構&#xff0c;常見的線性表&#xff1a;順序表、鏈表、棧、隊列、字符串… 線性表在…

GPT - 5被曝將在8月初發布!并同步推出mini、nano版

據《TheVerge》最新報道&#xff0c;OpenAI 正準備在 8 月發布新版本旗艦大模型 GPT-5&#xff0c;如果順利的話發布節點最早會在 8 月初。同時&#xff0c;下個月發布 GPT-5 時&#xff0c;還會一并推出 mini&#xff08;小型&#xff09;和 nano&#xff08;微型&#xff09;…

【Linux操作系統】簡學深悟啟示錄:Linux環境基礎開發工具使用

文章目錄1.軟件包管理器yum2.Linux編輯器vim2.1 三模式切換2.2 正常模式2.3 底行模式2.4 可視化模式2.5 vim 配置3.Linux編譯器gcc/g3.1 預處理3.2 編譯3.3 匯編3.4 連接3.5 函數庫4.Linux自動化構建工具Makefile5.Linux調試器gdb希望讀者們多多三連支持小編會繼續更新你們的鼓…

八大神經網絡的區別

神經網絡名稱全稱/修正名稱主要作用核心特點典型應用場景CINICNN&#xff08;卷積神經網絡&#xff09;處理圖像、視頻等空間數據&#xff0c;提取局部特征。使用卷積核、池化操作&#xff1b;擅長平移不變性。圖像分類、目標檢測、人臉識別。RINIRNN&#xff08;循環神經網絡&…

從 SQL Server 到 KingbaseES V9R4C12,一次“無痛”遷移與深度兼容體驗實錄

#數據庫平替用金倉 #金倉產品體驗官 摘要&#xff1a;本文以體驗項目案例為主線&#xff0c;從下載安裝、數據類型、T-SQL、JDBC、性能基準、踩坑回退六大維度&#xff0c;全景驗證 KingbaseES V9R4C12 對 SQL Server 的“零改造”兼容承諾&#xff1b;并給出 TPCH 100G 性能對…

EasyPlayer播放器系列開發計劃2025

EasyPlayer系列產品發展至今&#xff0c;已經超過10年&#xff0c;從最早的EasyPlayer RTSP播放器&#xff0c;到如今維護的3條線&#xff1a;EasyPlayer-RTSP播放器&#xff1a;Windows、Android、iOS&#xff1b;EasyPlayerPro播放器&#xff1a;Windows、Android、iOS&#…

通信名詞解釋:I2C、USART、SPI、RS232、RS485、CAN、TCP/IP、SOCKET、modbus等

以下內容參考AI生成內容1. I2C&#xff08;Inter-Integrated Circuit&#xff0c;集成電路間總線&#xff09;定義&#xff1a;由飛利浦&#xff08;現恩智浦&#xff09;開發的短距離串行通信總線&#xff0c;用于芯片級設備間的低速數據傳輸。工作原理&#xff1a;采用兩根信…

bash的特性-常見的快捷鍵

一、前言在 Linux Shell 編程和日常使用中&#xff0c;Bash 快捷鍵 是提升命令行操作效率的利器。熟練掌握這些快捷鍵&#xff0c;不僅可以節省大量輸入時間&#xff0c;還能顯著提升你在終端環境下的操作流暢度。本文將帶你全面了解 Bash 中常用的快捷鍵&#xff0c;包括&…

【Java Web實戰】從零到一打造企業級網上購書網站系統 | 完整開發實錄(三)

&#x1f3a8; 核心功能設計 &#x1f464; 用戶管理系統 用戶管理是整個系統的基礎&#xff0c;我設計了完整的用戶生命周期管理&#xff1a; &#x1f510; 用戶注冊流程 #mermaid-svg-D0eUHWissjNhkqlB {font-family:"trebuchet ms",verdana,arial,sans-serif;fon…

uniapp input 聚焦時鍵盤彈起滾動到對應的部分

實現效果代碼如下<template><view idapp><view class"aa"></view><iconfont name"left"></iconfont>姓氏&#xff1a;<input style"background-color: antiquewhite;" type"text" v-model&quo…

【基礎篇三】WebSocket:實時通信的革命

目錄 一、傳統HTTP的"痛點"分析 1.1 HTTP的單向通信模式 1.2 "實時"效果的痛苦嘗試 ?編輯 1.3 性能對比分析 二、WebSocket 協議詳解 2.1 WebSocket是什么&#xff1f; ?編輯 2.2 WebSocket的核心特性 2.2.1 全雙工通信&#xff08;Full-Duple…