11. 【C语言】表格与矩阵:多维数组
上一篇文章我们学会了一维数组——它像一排连续的抽屉整齐地排成一条直线。但现实中的数据往往比“一排”更复杂课程表有行有列棋盘有纵横坐标图像是由像素组成的矩形网格。这时候一维数组就有些力不从心了。好在 C 语言允许我们把这些“行”再堆叠起来形成多维数组。二维数组用得最多三维偶尔露脸四维以上更多是理论存在。今天就主要攻克二维再浅探多维让你以后碰到矩阵运算、图像处理、游戏棋盘之类的问题能心中有数。一、二维数组的声明与理解1. 声明方式类型 数组名[行数][列数];比如存储一个班级 3 门课、5 个学生的成绩表intscores[3][5];// 3 行 5 列它对应这样一张表学生0 学生1 学生2 学生3 学生4 课程0: ? ? ? ? ? 课程1: ? ? ? ? ? 课程2: ? ? ? ? ?逻辑上我们把它理解成“行”和“列”但在物理内存中它依然是一维连续排列的。C 语言用的是行优先存储先完整存第 0 行然后紧接着存第 1 行再存第 2 行……像把一张表格一行行拆开拼成一条长链。内存顺序: [0][0] [0][1] [0][2] [0][3] [0][4] [1][0] [1][1] ... [2][4]这个知识点非常重要。因为行优先访问scores[i][j]时编译器实际上计算的是地址偏移 i * 列数 j知道这个原理你以后写遍历循环时就会把行循环放外层、列循环放内层——尽量让内存访问连续能大幅提升性能缓存友好。2. 初始化二维数组完全初始化嵌套花括号intmatrix[2][3]{{1,2,3},{4,5,6}};结果为第0行: 1, 2, 3 第1行: 4, 5, 6部分初始化未指定的自动为 0intmatrix[2][3]{{1,2}// 第0行1, 2, 0第1行全0};省略内层花括号不推荐可读性差intmatrix[2][3]{1,2,3,4,5,6};// 按行优先依次填充省略第一维大小编译器根据初始化列表推断intmatrix[][3]{{1,2,3},{4,5,6}};// 自动推断为 2 行 3 列注意只有最左边的维度可以省略其他维度必须写清楚否则编译器算不出地址偏移公式。二、访问二维数组元素通过数组名[行下标][列下标]访问下标都从 0 开始。intmatrix[2][3]{{10,20,30},{40,50,60}};printf(%d\n,matrix[0][1]);// 20matrix[1][2]99;// 修改第1行第2列遍历二维数组通常用嵌套的for循环#includestdio.hintmain(void){intmatrix[2][3]{{1,2,3},{4,5,6}};for(inti0;i2;i){// 外层遍历行for(intj0;j3;j){// 内层遍历列printf(%d ,matrix[i][j]);}printf(\n);// 每行结束后换行}return0;}输出1 2 3 4 5 6遍历顺序很重要外层是行、内层是列才能让内存访问是连续的先 [0][0]、[0][1]、[0][2]然后 [1][0]…。如果反过来外层列、内层行CPU 缓存会频繁落空在大数据量下性能差距可达数倍。记住一个原则让内层循环对应最右边的下标。三、二维数组作为函数参数把二维数组传给函数时必须告诉编译器除了最左边维度以外的所有维度大小。voidprint_matrix(introws,intcols,intmat[][cols]){for(inti0;irows;i){for(intj0;jcols;j){printf(%d ,mat[i][j]);}printf(\n);}}注意参数int mat[][cols]最左边的维度行可以省略写成空的[]。列的大小必须给定因为编译器需要它来计算i * cols j的偏移。调用时intmatrix[2][3]{{1,2,3},{4,5,6}};print_matrix(2,3,matrix);四、经典案例矩阵运算矩阵加法是最直观的二维数组应用——两个相同大小的矩阵对应元素相加。#includestdio.h#defineROWS2#defineCOLS3voidadd_matrices(inta[ROWS][COLS],intb[ROWS][COLS],intresult[ROWS][COLS]){for(inti0;iROWS;i){for(intj0;jCOLS;j){result[i][j]a[i][j]b[i][j];}}}voidprint_matrix(introws,intcols,intmat[][cols]){for(inti0;irows;i){for(intj0;jcols;j){printf(%3d ,mat[i][j]);}printf(\n);}}intmain(void){intA[ROWS][COLS]{{1,2,3},{4,5,6}};intB[ROWS][COLS]{{6,5,4},{3,2,1}};intC[ROWS][COLS]{0};add_matrices(A,B,C);printf(矩阵 A:\n);print_matrix(ROWS,COLS,A);printf(\n矩阵 B:\n);print_matrix(ROWS,COLS,B);printf(\nA B \n);print_matrix(ROWS,COLS,C);return0;}输出矩阵 A: 1 2 3 4 5 6 矩阵 B: 6 5 4 3 2 1 A B 7 7 7 7 7 7%3d让每个数字占 3 个字符宽度排版整齐。二维数组在数值计算、图像处理中无处不在——图像本身就是一个像素值的二维数组核心操作几乎都是对行列的遍历。五、多维数组三维及更高二维之上可以扩展出三维、四维乃至更高维度的数组。三维数组可以理解为“多页表格”——每一“页”是一个二维矩阵。// 2页每页3行4列intcube[2][3][4]{{// 第0页{1,2,3,4},{5,6,7,8},{9,10,11,12}},{// 第1页{13,14,15,16},{17,18,19,20},{21,22,23,24}}};遍历三重循环for(intp0;p2;p){for(inti0;i3;i){for(intj0;j4;j){printf(%2d ,cube[p][i][j]);}printf(\n);}printf(---\n);}更高维度同理层层嵌套。但维度越高对内存的消耗呈指数增长实际开发中很少超过三维。保持对高维数组“层层嵌套”的感知即可。六、字符串数组与命令行参数预告二维char数组的一个典型用途是存储多个字符串charnames[3][20]{Alice,Bob,Charlie};这里names[0]是一个长度为 20 的字符数组存放Alice带\0结尾。后面我们讲到字符串、指针数组时会深入这个主题包括argv命令行参数的本质。七、常见错误与陷阱下标顺序搞反intmat[3][5];mat[0][1]10;// 正确mat[1][0]20;// 正确// 不要写成 mat[1,0]那是逗号运算符结果是 0给二维数组赋值忘记列下标intmat[2][3];mat[0]{1,2,3};// 错误数组名不能赋值只能逐个元素赋值或者在声明时整体初始化。传递二维数组时漏写列数voidfunc(intmat[][])// 错误必须指定列数voidfunc(intmat[3][])// 也错列数必须给出voidfunc(intmat[][5])// 正确把sizeof用在函数参数里的二维数组voidfunc(intmat[][5]){introwssizeof(mat)/sizeof(mat[0]);// 错误mat 是指针}和一维数组一样函数参数中的数组名退化为指针sizeof失效。遍历时行列循环写反导致性能骤降内层循环应遍历最右边的下标保证内存访问连续。八、小结今天你把一维的“队伍”扩展成了二维的“矩阵”还学会了更高维度的基本概念。二维数组是图像处理、游戏开发、科学计算中的核心数据结构矩阵的加法、乘法、转置都建立在它之上。你学到的“行优先存储”和遍历原则以后也会直接影响程序的运行速度。现在我们已经能管理大量的数据了但代码依然堆在main函数里。当程序逐渐庞大单靠main是远远不够的——你需要把功能拆分成可复用的模块。下一篇文章我们就进入函数的世界如何把代码封装成函数如何传递参数如何获得返回值。它会让你的代码从“长篇大论”进化成“团队协作”。课后小练习声明一个 3×3 的矩阵初始化为 1 到 9按行递增。打印出它的转置矩阵行列互换。实现两个 3×3 矩阵的乘法并打印结果。矩阵乘法的规则C[i][j] sum(A[i][k] * B[k][j])k 从 0 到 2。用二维数组打印一个 5×5 的单位矩阵对角线为 1其余为 0。小挑战输入一个 3×3 的整数方阵判断它是否为幻方即每行、每列、两条对角线的和都相等。输出判断结果。我们下期见获取本系列示例代码请访问 GitCode 仓库。

相关新闻

10. 【C语言】把数据排成队:一维数组

10. 【C语言】把数据排成队:一维数组

上一篇我们学会了循环,程序终于可以不知疲倦地重复干活了。但这时候一个尴尬的问题浮出水面:如果我要存储一个班 50 个学生的成绩,难道要定义 score1, score2, score3 ... score50 一共 50 个变量吗? 真要这样写,别说…

2026/7/5 14:57:36阅读更多 →
9. 【C语言】重复是力量:C语言循环结构

9. 【C语言】重复是力量:C语言循环结构

前几篇文章,我们让程序有了记忆(变量),会说话(输入输出),还学会了判断(分支)。但程序还有一个让人类望尘莫及的本事:不知疲倦地重复做一件事。 想想看&#…

2026/7/5 14:57:36阅读更多 →
4-20mA电流环检测与PIC单片机信号处理方案

4-20mA电流环检测与PIC单片机信号处理方案

1. 4-20mA电流环基础与行业应用工业现场最可靠的信号传输方式莫过于4-20mA电流环,这个看似简单的标准已经统治过程控制领域半个多世纪。电流信号相比电压信号具有显著优势:抗干扰能力强,可长距离传输(理论可达数公里)&…

2026/7/5 14:57:36阅读更多 →
5个关键设计揭秘:Vanguard内核驱动如何构建游戏反作弊的底层防线

5个关键设计揭秘:Vanguard内核驱动如何构建游戏反作弊的底层防线

5个关键设计揭秘:Vanguard内核驱动如何构建游戏反作弊的底层防线 【免费下载链接】Vanguard Official Vanguard Anti-Cheat source code. 项目地址: https://gitcode.com/gh_mirrors/va/Vanguard Vanguard内核驱动作为Riot Games官方开源的游戏反作弊系统&am…

2026/7/5 16:02:47阅读更多 →
IDM激活脚本终极指南:如何免费解锁完整版下载管理器

IDM激活脚本终极指南:如何免费解锁完整版下载管理器

IDM激活脚本终极指南:如何免费解锁完整版下载管理器 【免费下载链接】IDM-Activation-Script An open-source tool to activate and reset the trial of Internet Download Manager. 项目地址: https://gitcode.com/gh_mirrors/idma/IDM-Activation-Script I…

2026/7/5 16:02:47阅读更多 →
ESP-Drone完整指南:基于ESP32的开源无人机终极解决方案

ESP-Drone完整指南:基于ESP32的开源无人机终极解决方案

ESP-Drone完整指南:基于ESP32的开源无人机终极解决方案 【免费下载链接】esp-drone Mini Drone/Quadcopter Firmware for ESP32 and ESP32-S Series SoCs. 项目地址: https://gitcode.com/GitHub_Trending/es/esp-drone ESP-Drone是基于乐鑫ESP32/ESP32-S2/E…

2026/7/5 16:02:47阅读更多 →
Kali Linux无线渗透测试实战:从环境搭建到完整工作流详解

Kali Linux无线渗透测试实战:从环境搭建到完整工作流详解

1. 项目概述:为什么你需要一套完整的无线渗透工具集? 如果你是一名网络安全爱好者、渗透测试工程师,或者只是对自己家WiFi的安全性感到好奇,那么“无线渗透测试”这个概念对你来说一定不陌生。它听起来很酷,甚至有点黑…

2026/7/5 16:02:47阅读更多 →
告别SQL困境:Chat2DB AI智能数据库工具让你3分钟上手数据查询

告别SQL困境:Chat2DB AI智能数据库工具让你3分钟上手数据查询

告别SQL困境:Chat2DB AI智能数据库工具让你3分钟上手数据查询 【免费下载链接】Chat2DB AI-driven database tool and SQL client, The hottest GUI client, supporting MySQL, Oracle, PostgreSQL, DB2, SQL Server, DB2, SQLite, H2, ClickHouse, and more. 项目…

2026/7/5 16:02:47阅读更多 →
终极Yaconf实战指南:三步构建PHP高性能配置中心

终极Yaconf实战指南:三步构建PHP高性能配置中心

终极Yaconf实战指南:三步构建PHP高性能配置中心 【免费下载链接】yaconf A PHP Persistent Configurations Container 项目地址: https://gitcode.com/gh_mirrors/ya/yaconf 第一部分:为什么传统配置管理让PHP应用变慢? 在PHP应用开发…

2026/7/5 15:57:46阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/5 0:01:08阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/5 0:01:08阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/5 0:01:08阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/5 0:01:08阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/5 0:01:08阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/5 0:01:08阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/5 1:30:27阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/5 3:48:10阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/5 3:48:09阅读更多 →