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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…