C语言数组介绍 -- 一维数组和二维数组的创建、初始化、下标、遍历、存储,C99 变长数组

目录

1. 一维数组

1.1 数组的概念

1.2 一维数组的创建

1.3 一维数组的初始化

1.4 数组的类型

1.5 数组下标

1.5.1 数组元素的遍历

1.5.2 数组的输入

1.6 一维数组在内存中的存储

1.7 sizeof 计算数组元素个数

2. 二维数组 

2.1 二维数组的创建

2.2 二维数组的初始化

2.2.1 不完全初始化

2.2.2 完全初始化

2.2.3 按行初始化

2.2.4 初始化时省略行,但是不能省略列

2.3 二维数组的下标

2.3.1 二维数组的遍历

2.4 二维数组在内存中的存储

3. C99 中的变长数组


1. 一维数组

1.1 数组的概念

        数组是一组相同类型元素的集合。(1)数组中存放的是 1 个或者多个元素,数组元素个数不能为 0。(2)数组中存放的数据的类型是相同的。

1.2 一维数组的创建

        一维数组创建的基本语法:

type  arr_name[常量值];

        type:数组中元素的数据类型(char,int,struct 等)。

        arr_name:数组名。

        常量值:表示数组的大小。 

int math[20];    // 创建 math 数组用于存储 20 人的数学成绩,数据成绩的类型为 int
double score[10];    // 创建 score 数组用于存储 10 个人得分情况,得分的类型为 double

1.3 一维数组的初始化

        数组在创建的时候,给定一些初始值,就叫做数组的初始化。 数组的初始化一般使用大括号,将数据放在大括号中。初始化的时候给定元素个数不能超过数组的大小。

#include <stdio.h>int main()
{int arr1[5] = {1, 2, 3, 4, 5};	// 完全初始化int arr2[6] = { 1, 5 };	// 不完全初始化:前面元素为给定的值,剩余的元素默认初始化为 0。int arr3[7];    // 定义数组的时候可以不初始化,但是默认为随机值。return 0;
}

1.4 数组的类型

        数组也是有类型的,数组算是一种自定义类型,去掉数组名留下的就是数组的类型

int arr1[10];int arr2[12];char ch[5];

        arr1 数组的类型是 int [10],arr2 数组的类型是 int [12],ch 数组的类型是 char [5]。 

1.5 数组下标

        C 语言规定数组是有下标的,下标从 0 开始,假设数组有 n 个元素,最后一个元素的下标是 n - 1 ,下标就相当于数组元素的编号,如下:

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

        C 语言数组的访问提供了一个操作符 " [] ",这个操作符叫做下标访问操作符。 

         有下标访问操作符,就可以轻松访问数组的元素了。访问下标为 7 的元素,就使用 arr[7],如下:

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

1.5.1 数组元素的遍历

        可以通过 for 循环 + 下标的方式对整个数组的元素进行遍历。

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

1.5.2 数组的输入

        想对数组中的元素进行修改,可以使用 scanf 进行输入对数组的元素进行修改

#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int i = 0;for (i = 0; i < 10; i++){scanf("%d", &arr[i]);}for (i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

        注:scanf 访问数组中单独的一个元素的时候需要加上取地址运算符。 

1.6 一维数组在内存中的存储

        我们可以通过打印数组每个元素的地址来观察数组在内存中是如何存储的

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

        从输出的结果上可以看出来,数组随着下标的增长,地址是由小变大的,并且每两个响铃的元素之间相差 4,这是因为这个数组中目前存储的数据类型为 int 类型,int 类型每一个元素需要 4 个字节进行存储。

        所以可以得出结论:数组在内存中是连续存放的。 

1.7 sizeof 计算数组元素个数

        如果想直到数组的元素个数,可以使用 sizeof 关键字来计算类型或者变量的大小,sizeof 返回的并不是数组的元素个数,返回的是数组占据多少字节,可以通过占据的字节数除以数组中数据类型的方式来计算数组中的元素个数

#include <stdio.h>int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int i = 0;printf("数组占用的字节数: %d\n", sizeof(arr));printf("数组中一个元素的大小: %d\n", sizeof(arr[0]));//计算⼀个元素的⼤⼩,单位是字节int sz = sizeof(arr) / sizeof(arr[0]);printf("数组中元素的个数: %d\n", sz);return 0;
}

2. 二维数组 

2.1 二维数组的创建

        把一维数组作为数组的元素时,这时候该数组就是二维数组。同理将二维数组作为数组的元素时,这时候该数组就是三位数组。二维数组以上的数组统称为多维数组。

        创建二维数组的语法如下:

type arr_name[常量值1][常量值2];

         type:表示二维数组中数据的类型。

        arr_name:表示二维数组的数组名。

        常量1:表示二维数组的行数。

        常量2:表示二维数组的列数。

int arr[3][5];
double data[2][8];

        上述中 arr 表示为一个 3 行 5 列的二维数组,存储的数据类型为 int 类型;data 表示为一个 2 行 8 列的二维数组,存储的数据类型为 double 类型。 

2.2 二维数组的初始化

2.2.1 不完全初始化

#include <stdio.h>int main()
{int arr1[3][5] = { 1, 2, 3, 4, 5, 6, 7};int arr2[3][5] = { 0 };return 0;
}

        如上,可以看出,当对二维数组进行初始化的时候,是一行一行进行初始化的,等该行初始化完,在继续初始化下一行,并且剩余没有初始化的元素默认初始化为 0

2.2.2 完全初始化

#include <stdio.h>int main()
{int arr3[3][5] = { 1,2,3,4,5,2,3,4,5,6,3,4,5,6,7 };return 0;
}

2.2.3 按行初始化

#include <stdio.h>int main()
{int arr4[3][5] = { {1,2},{3,4},{5,6} };return 0;
}

2.2.4 初始化时省略行,但是不能省略列

int arr5[][5] = { 1,2,3 };
int arr6[][5] = { 1,2,3,4,5,6,7 };
int arr7[][5] = { {1,2}, {3,4}, {5,6} };

2.3 二维数组的下标

        二维数组是有行有列的,只要锁定行和列就能锁定数组中唯一的一个元素

        C语⾔规定,⼆维数组的⾏是从0开始的,列也是从0开始的,如下所示:

int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

        如果想要访问 7 这个数组,那么就可以通过  arr[2][4] 进行访问。

#include <stdio.h>int main()
{int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };printf("%d\n", arr[2][4]);return 0;
}

2.3.1 二维数组的遍历

        一维数组是使用 for 循环 + 数组下标的方式进行遍历的,那么二维数组也可以通过同样的方式对数组进行遍历,只是遍历二维数组的时候需要两层 for 循环。下列就通过遍历的方式向二维数组中输入数据并通过 printf 打印出来。

#include <stdio.h>int main()
{int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };int i = 0;//遍历⾏//输⼊for (i = 0; i < 3; i++) //产⽣⾏号{int j = 0;for (j = 0; j < 5; j++) //产⽣列号{scanf("%d", &arr[i][j]); //输⼊数据}}printf("\n");//输出for (i = 0; i < 3; i++) //产⽣⾏号{int j = 0;for (j = 0; j < 5; j++) //产⽣列号{printf("%d ", arr[i][j]); //输出数据}printf("\n");}return 0;
}

2.4 二维数组在内存中的存储

        像一维数组一样,通过打印出二维数组每个元素的地址观察二维数组中元素的存储方式

#include <stdio.h>int main()
{int arr[3][5] = { 0 };int i = 0;int j = 0;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++){printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);}}return 0;
}

        从上述的输出结果可以看出,每一行内部的每个元素都是相邻的,地址之间相差 4 个字节,跨行位置处的两个元素也是相邻的,也只相差 4 个字节,所以二维数组中的每个元素都是连续存放的。 

3. C99 中的变长数组

        在 C99 标准之前,C 语言在创建数组的时候,数组大小的指定只能使用常量、常量表达式。这样的语法限制在创建数组的时候不够灵活,有时候数组创建大了会造成空间浪费,有时候数组创建小了又不够用。

        C99 中给出一个变长数组(variable-length array,VLA)的新特性,允许我们可以使用变量指定数组大小

int n = a+b;
int arr[n];

        上面示例中,arr 数组就是变长数组,因为它的长度取决于变量 n 的值,编译器在编译的时候无法确定 n 的值为多少,只有运行时才能知道  n 是多少

        变长数组的根本特征就是数组长度只有运行时才能确定,所以变长数组不能初始化。好处是在开发时不用随意为数组指定一个估计的长度,可以在运行时为数组分配精确的长度。变⻓数组的意思是数组的大小是可以使⽤变量来指定的,在程序运⾏的时候,根据变量的⼤⼩来指定数组的元素个数,⽽不是说数组的⼤⼩是可变的。数组的大小⼀旦确定就不能再变化了

         在 VS2022 上虽然支持大部分 C99 语法,但是没有支持 C99 变长数组,下面是在 gcc 编译器上测试的结果:

#include <stdio.h>int main()
{int n = 0;scanf("%d", &n);int arr[n];int i = 0;for (i = 0; i < n; i++){scanf("%d", &arr[i]);}for (i = 0; i < n; i++){printf("%d ", arr[i]);}printf("\n");return 0;
};

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/86088.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/86088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringAI + DeepSeek大模型应用开发 - 进阶篇(上)

三、SpringAI 2. 哄哄模拟器 2.1 提示词工程 提示词工程&#xff08;Prompt Engineering&#xff09;&#xff1a;通过优化提示词&#xff0c;使大模型生成尽可能理想的内容&#xff0c;这一过程就叫提示词工程。 &#xff08;1&#xff09;清晰明确的指令 谈谈人工智能 …

Spring Boot实现异常处理

Spring Boot 提供了多种灵活的方式实现异常处理&#xff0c;以下是核心方案和最佳实践&#xff1a; 一、基础异常处理方案 1. ControllerAdvice ExceptionHandler&#xff08;全局处理&#xff09; ControllerAdvice public class GlobalExceptionHandler {// 处理特定异常&…

【目标检测】IOU的概念与Python实例解析

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

Vue2中如何使用vue-print-nb打印功能

插件官网地址&#xff1a;vue-print-nb - npm 1.安装 npm install vue-print-nb --save 2.导入打印插件 //main.js import Print from vue-print-nb Vue.use(Print); 3.配置参数 4.页面使用 <div id"printDiv">打印内容</div><el-button v-print&…

Matplotlib快速入门

目录 基本使用 解决中文乱码 一个坐标系绘制多个图像 多个坐标系绘制 基本使用 什么是Matplotlib 是专门用于开发2D图表(包括3D图表)以渐进&#xff0c;交互式方式实现数据可视化 为什么要学习matplotlib 可视化是在整个数据挖掘的关键辅助工具&#xff0c;可以清晰的理解…

扣料不允许‘货物移动’

遇到了报错&#xff0c;不允许货物移动 以为又是和之前一样是订单已经关闭&#xff0c;看是领错料还是财务误关的原因&#xff0c;但是co03一看订单状态并没有关闭 原因就是这个CRTD 订单只是创建了&#xff0c;但是没有下达 找个正常的看看&#xff1a; 一般订单创建和下达都…

【AI】全新AI测试系列之二--------AI自动化测试,提高测试效率

目录 一、自动化测试 1、与手动测试对比 2、自动化测试流程 二、自动化测试环境搭建 三、web自动化使用AI的两种方式 1、利用DeepSeek快速生成脚本 2、pycharm集成通义灵码 四、通义灵码实战 1、使用提示词生成代码 2、使用pytest框架 前言&#xff1a;上一章节只要是…

npm包冲突install失败

--legacy-peer-deps是npm&#xff08;Node.js包管理器&#xff09;的一个命令行选项&#xff0c;主要用于解决依赖冲突问题。当安装依赖时&#xff0c;npm默认会严格检查peer dependencies&#xff08;对等依赖&#xff09;的版本兼容性&#xff0c;可能导致安装失败。启用此选…

68、数据访问-crud实验-删除用户完成

68、数据访问-crud实验-删除用户完成 以下是完成“数据访问-CRUD实验-删除用户”功能的一般步骤&#xff0c;以常见Web应用框架&#xff08;如Spring Boot MyBatis-Plus、Django、Ruby on Rails&#xff09;为例&#xff1a; #### 准备工作 - **数据库表设计**&#xff1a;确…

实现 TurtleBot3 多点轨迹跟踪导航

系统架构 move_base本身不支持一次性发送多个目标点并自动按顺序导航,使用nav_msgs/Path消息类型发布多个路径点,然后让机器人按顺序依次到达每个路径点。 发布一个包含多个路径点的Path消息(可选,用于在RVIZ中显示路径)。按顺序将每个路径点作为MoveBaseGoal发送给move_…

《人性的优点》:破解忧虑密码,构建积极人生

我强烈推荐4本可以改变命运的经典著作&#xff1a; 《寿康宝鉴》在线阅读白话文《欲海回狂》在线阅读白话文《阴律无情》在线阅读白话文《了凡四训》在线阅读白话文 一、世界观&#xff1a;忧虑的本质与生命的真相 &#xff08;一&#xff09;忧虑是精神的“虚构苦难” 卡耐基…

D2554探鸽协议,sensor属性,回调

D2554探鸽协议&#xff0c;sensor属性&#xff0c;回调 各属性的默认值 对比度&#xff1a; 0x4064&#xff08;10进制&#xff09; 清晰度、锐度&#xff1a; 0x000&#xff08;10进制&#xff09; 饱和度&#xff1a; …

.NET 4.7中使用NLog记录日志到数据库表

1. 首先安装必要的NuGet包 在项目中安装以下NuGet包&#xff1a; NLog NLog.Config (可选&#xff0c;用于自动生成配置文件) 相应的数据库提供程序&#xff08;如System.Data.SqlClient for SQL Server&#xff09; Install-Package NLog Install-Package NLog.Config In…

非对称加密实战:Python实现数字签名

目录 非对称加密实战&#xff1a;Python实现数字签名引言&#xff1a;数字世界的身份验证1. 非对称加密基础1.1 核心概念1.2 非对称加密算法比较 2. 数字签名原理2.1 数字签名工作流程2.2 数字签名的核心特性 3. RSA数字签名实现3.1 RSA算法数学基础3.1.1 密钥生成3.1.2 签名生…

优化提示词的常用技巧

优化提示词的常用技巧 1. 告诉AI你需要的重要要素 &#xff08;1&#xff09;风格&#xff1a;明确语言风格 优化前&#xff1a;写一篇人工智能的介绍。优化后&#xff1a;写一篇100字的人工智能介绍&#xff0c;受众是小学生&#xff0c;语言幽默。 &#xff08;2&#xf…

PyTorch实战(12)——StyleGAN详解与实现

PyTorch实战(12)——StyleGAN详解与实现 0. 前言1. StyleGAN1.1 模型介绍1.2 模型策略分析2. 实现 StyleGAN2.1 生成图像2.2 风格迁移小结系列链接0. 前言 StyleGAN (Style-Generative Adversarial Networks) 是生成对抗网络 (Generative Adversarial Networks, GAN) 的变体…

XML重复查询一条Sql语句??怎么解决

一、核心问题&#xff1a;从SQL重复执行到日志失效 1. 首要现象&#xff1a;XML重复查询失效 在排查服务性能时发现&#xff1a; <!-- MyBatis XML片段 --> <select id"List" resultMap"Map"> SELECT * FROM user WHERE name #{name} …

量化面试绿皮书:33. 不公平的硬币

文中内容仅限技术学习与代码实践参考&#xff0c;市场存在不确定性&#xff0c;技术分析需谨慎验证&#xff0c;不构成任何投资建议。 33. 不公平的硬币 你有1000枚硬币。 其中&#xff0c;有1枚硬币正反两面都是正面。 其他的999枚硬币都是公平的硬币。 你随机选择一枚硬币并…

Java 期末考试题

1. 如果将类 MyClass 声明为 public&#xff0c;它的文件名必须是 ( ) 才能正常编译。 解&#xff1a;① 如果一个类被声明为 public&#xff0c;则必须以 .java 作为文件拓展名。 答案&#xff1a;MyClass.java 2. 定义类头时能使用的修饰符是&#xff08; &#xff09;…

跨标签页通信(三):Web Storage

在现代 Web 应用中&#xff0c;跨标签页通信的需求越来越普遍。无论是实现多标签页之间的数据同步&#xff0c;还是构建实时协作功能&#xff0c;跨标签页通信都能极大地提升用户体验。今天&#xff0c;我们将探讨一种简单而高效的实现方式&#xff1a;Web Storage。 一、什么…