数组

数组的引入

  • 如果要在程序中保存一个人的年龄?如何保存?

    答:创建一个基于int类型的变量,举例:int age = 22

  • 如果要在程序中保存一个人的三门课的成绩?如何保存?

    答:创建三个基于float类型的变量,举例:float score1 score2 score3;

    • 保存一个人15门课程的成绩?如何保存? -----数组

数组的概念

什么是数组

定义:数组是相同类型有序数据的集合。

在这里插入图片描述

数组的特征

  • 数组中的数据被称为数组的元素所谓的元素,其实就是数组的每一个匿名的变量空间),是同构。
  • 数组中的元素存放在内存空间(char player_name[6]: 申请在内存中开辟6块连续的基于char类型的变量)
衍生概念:下标(索引)
  • 下标(索引)代表了数组中元素距离第一个元素(首地址所在的元素)的偏移量。 举例:第一个元素距离第一个元素的偏移量是0,所以数组中的下标是从0开始的。

在这里插入图片描述

  • 数组的下标是从0开始的:

数组的最大下标 = 数组的元素个数(数组的大小或容量) - 1

int a:在内存中开辟1块空间,该空间的大小是4个字节。

int a1,a2,a3,a4,a5:在内存中开辟连续的5块空间,每一块空间的大小是4个字节。但是不如数组方便。

int arr[5]:在内存中开辟连续的5块空间,每一块空间的大小是4个字节。

一维数组

数组的定义

语法:

数据类型 数组名[数组容量];

注意:数据类型又被称作类型说明符,数组容量又被称作数组元素个数或者数组的大小/长度

说明:

  • 数组的数据类型由数组中的元素来决定。也就是说数据类型,由元素的类型来决定,元素是什么类型,数组就是什么类型。同一个数组中,所有元素的类型都是一致的。

  • 数组名也是标识符,我们所说的数组(名),大家可以理解为数据类型是数组的变量(名)。命名规则与变量的规则一样,唯一的区别是变量使用单数,数组使用复数。也就是以字母或者下划线开头,后面只能跟字母、数字、下划线。

  • 数组容量还可以叫做常量表达式。**其值必须是整数。**关于数组容量的类型:

    • C89标准:只支持常量和符号常量,不支持变量。

      #define SIZE 5   // 符号常量,使用宏定义int lenght = 5;  // 变量int arr1[5];     // 常量(字面量)正确
      int arr2[SIZE];  // 符号常量,正确
      int arr3[length];// 变量,C89错误
      
    • C99标准(大部分环境支持):引入==变长数组(VLA)==的概念,就是可以使用变量,数组在运行的时候决定大小。举例:

      int length = 5;  // length = 5; 创建一个变量length,赋值5
      int arr[length]; // 创建一个容量为5的数组,C99标准下是正确的(执行这句的代码的时候,已经在内存申请空间)
      length = 10;     // 此时虽然变量length的值变成了10,但是已经创建的数组的大小是不会改变的。数组大小依然是5

类型:

​ 代表了数组中元素的类型,数组的空间大小 = 数组中所有元素空间之和。

容量:

​ 数组中能存储多少个元素,数组容量一定是一个整型。

深入理解:

​ ① 定义一个数组,相当于申请了一个可以容纳所指定元素个数的内存单元。所申请的内存单元是连续的。

​ ② 定义一个数组,相当于定义了多个匿名的变量,这些变量可以通过数组名[下标]来访问。

范例:

// 定义一个数组
int arr[10]; // 定义一个存放10个int类型元素的数组

关于数组中元素默认值问题:

  • **全局作用域和static修饰的变量:**元素的默认值是0

  • 局部作用域:元素的默认值是随机值,此时强烈建议用户初始化

    举例:

    #include <stdio.h>int g_age;    // 全局作用域,定义在函数的外面,默认值是0
    int g_ages[5];// 全局作用域,等同于全局变量,元素的默认值是0int main(int argc, char *argv[])
    {int p_age;   // 局部作用域:函数中定义的所有的变量都属于局部作用域。变量使用前需要初始化。int p_ages[5]; // 局部作用域:元素的值使用前需要初始化return 0;
    }
    

    **注意:关于默认值 ,整型和浮点型的默认值是0,字符型的默认值是\0\0**对应的ASCII码为0

数组元素的访问

原则:

数组中的元素不能一次性访问所有,只能一个一个的访问。

语法:

  • 取值:

    数组名[下标];
    
  • 赋值:

    数组名[下标] =;
    

举例:

// 定义一个存储10个元素的int数组
int arr[10];// 给数组的第一个元素进行赋值
arr[0] = 88;// 访问数组的第一个元素
int a = arr[0];// 修改数组中第一个元素的值
arr[0] = 66; // 使用66覆盖88int c = arr[9]; // 如果是一个局部作用域的数组,此时访问的元素的值是 随机值;如果是全局作用域,值是0
int b = arr[10];// error,报一个错误:下标越界异常,因为访问了一个未知的存储空间

案例

  • 需求:利用循环给数组元素a[0]~a[9]赋值0~9,并且要求逆序输出。

  • 代码:

    #include <stdio.h>int main(int argc,char *argv[])
    { // 创建一个数组,用来存放0~9int arr[10];// 计算数组的大小:数组大小 = 数组所有元素的总字节数 / 每一个元素的字节数 需要使用到sizeof运算符int len = sizeof(arr) / sizeof(arr[0]);// 通过for循环给数组赋予0~9for (int i = 0; i <= 9; i++) arr[i] = i;// 逆序输出数组中的元素:数组最大下标 = 数组大小 - 1// 使用for循环获取数组每一个元素称之为数组的遍历for (int j = len -1; j >= 0; j--) printf("%4d", arr[j]);printf("\n");return 0;
    }

    结果:在这里插入图片描述

数组的初始化

说明:所谓的初始化,就是定义数组的时候,用指定的数据给对应的元素赋值。

语法:

数据类型 数据组[数组容量] = {...};

在这里插入图片描述

注意事项:

  • 数组可以部分初始化:也就是可以给数组中的前几个元素初始化,未被初始化的元素系统将自动初始化,初始值是0。(也就是一个数组织中,一旦有元素被初始化,剩余的元素将自动初始化为0
// 数组的部分初始化
int arr[10] = {11,12,13,14,15};  // 推荐写法:只初始化前5个元素,剩余元素系统默认为0,等价于下面写法
int arr[10] = {11,12,13,14,15,0,0,0,0,0};char arr1[5] = {'a','b','c'}; // 推荐写法,等价于下面写法
char arr1[5] = {'a','b','c','\0','\0'}; // 等价于下面写法
char arr1[5] = {'a','b','c',0,0}; // '\0' 对应的ASCII码是 0   char a = 'A' 等价于 char a = 65int arr2[5] = {}; // 等价于下面第三种写法
int arr2[5] = {0};// 等价于下面第三种写法,推荐
int arr2[5] = {0,0,0,0,0};
  • 数组根据初始化的元素自动分配大小:如果定义数组时未指定数组容量,则系统会根据初始化的元素的个数来决定容量。

    // 由初始化的元素来决定数组的容量
    int arr[] = {11,12,13,14,15}; // 推荐写法,等价于下面写法
    int arr[5] ={11,12,13,14,15}; 
    

案例

案例1
  • 需求:求斐波拉契数列,限制在20个。

  • 分析:1,1,2,3,5,8…

  • 代码:

    #include <stdio.h>int main(int argc,char *argv[])
    {//定义循环变量int i;//定义一个数组,用来存储20个数列int f[20] = {1,1};//计算数组的大小int len = sizeof(f) / sizeof(f[0]);//通过一个for循环完成数列for( i = 2; i < len; i++) f[i] = f[i-1] + f[i-2];//{1,2,3,4}//遍历数组for(i = 0; i < len;i++){//一行显示5个数if (i > 0 && i % 5 == 0) printf("\n");printf("%8d",f[i]);}printf("\n");return 0;
    }

    结果:

    在这里插入图片描述

案例2
  • 需求:从键盘输入年、月、日,计算并输出该日是该年第几天。

  • 分析:

    • 首先创建一个数组,用来存放每一个月的天数,因为二月特殊,初始化的时候,默认为平年天数。
    • 从控制台输入年,月,日
    • 闰年校验:如果是闰年,就修改数组中二月份对应的天数(平年:28天,闰年:29天)。
    • 定义一个变量,用来记录天数,默认就是我们输入的天数。
    • 遍历数组,将输入月份之前的每一个月的天数取出来加到记录天数的变量中。
    • 将统计后的天数打印输出。
  • 代码:

    #include <stdio.h>int main(int argc,char *argv[])
    {// 首先创建一个数组,用来存放每一个月的天数,因为二月特殊,初始化的时候,默认为平年天数。int t[] = {31,28,31,30,31,30,31,31,30,31,30,31};// 从控制台输入年,月,日int year,month,day;printf("请输入年份、月份、天(yyyy-MM-dd):");scanf("%d-%d-%d", &year, &month, &day);// 闰年校验:如果是闰年,就修改数组中二月份对应的天数(平年:28天,闰年:29天)。if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) t[1] = 29;// 定义一个变量,用来记录天数,默认就是我们输入的天数。int sum = day;// 遍历数组,将输入月份之前的每一个月的天数取出来加到记录天数的变量中。for (int i = 0; i < month - 1; i++) sum += t[i];// 将统计后的天数打印输出。printf("%d月%d日是%d年的第%d天!\n", month, day, year, sum);return 0;
    }

    结果:
    在这里插入图片描述

二维数组

定义

二维数组本质上是一个行列式组合,也就是说二维数组是由两部分组成,属于多维数组。二维数组通过行和列解读(先行后列

二维数组可被视为一个特殊的一维数组,也就是说,当一个数组中的每一个元素是一位数组的时候,那么这个数组就是二维数组。

语法

数据类型 数组名[行容量][列容量];  

行容量:外层数组的数组容量

列容量:内存数组的数组容量

说明

  • 二维数组在初始化的时候,可以省略行数,系统会通过初始化后的数据自动推断行数。
  • 二维数组和一位数组一样,也可以部分初始化,未初始化的元素使用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列对应的元素

注意:使用数组元素的下标应在已定义数组的大小范围内;应注意区别定义数组大小和引用数组元素的区别。

初始化

  • 分行给二维数组赋初值

    int arr[3][4] = {{11,12,13,14},{21,22,23,24},{31,32,33,34}};
    
  • 可将所有数据写在一个{}内,按照排列顺序对运算赋值

    int arr[3][4] = {11,12,13,14,21,22,23,24,31,32,33,34};
    
  • 可对部分元素赋初值,其余未初始化部分自动填充0

    int arr[3][4] = {{11},{21,22},{31,32,33}};
    
  • 若对全部元素赋初值,自定义数组时可以省略第一维数组容量(行容量),第二维数组容量(列容量)必须指明。

    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};
    
  • 在分行赋初值时,也可以省略第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]);
      
  • 代码:

    #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;
    }
  • 运行结果:

    在这里插入图片描述

案例2
  • 需求:矩阵的转置

  • 分析:

    • 所谓的转置,就是原本的列变行,行变列。

  • 代码:

    #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;
    }
  • 运行结果:
    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

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

相关文章

如何区别HTML和HTML5?

要区分 HTML&#xff08;通常指 HTML4 及更早版本&#xff09;和 HTML5&#xff0c;主要可以从以下关键方面进行比较&#xff1a;一、文档声明区别 <!-- HTML4 文档声明 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http:/…

Java实战:实时聊天应用开发(附GitHub链接)

一、前置技术项目介绍&#xff1a; 项目为局域网沟通软件&#xff0c;类似内网通&#xff0c;核心功能包括昵称输入、聊天界面展示在线人数&#xff08;实时更新&#xff09;、群聊&#xff0c;也可扩展私聊、登录注册、聊天记录存储等功能&#xff0c;结尾附GitHub链接。项目涉…

linux 的list_for_each_entry

linux的宏定义提高了代码的简洁性&#xff0c;但有时候的命名不够完美。比如list_for_each_entry&#xff0c;看名字只知道是遍历list&#xff0c;但一看里面的三个变量参数&#xff0c;有点懵逼。/*** list_for_each_entry - iterate over list of given type* pos: …

分布式面试点

目录 1.分布式理论 为什么CAP不可兼得呢? 2.CAP对应的模型和应用 3.Base理论 4,有哪些分布式锁的案例 5.分布式事务 6.Seata 分布式一致性算法 1. 准备阶段&#xff08;Prepare Phase&#xff09; 2. 接受阶段&#xff08;Accept Phase&#xff09; 3. 学习阶段&…

Neo4j系列---【Linux离线安装neo4j】

Linux离线安装neo4j 1.官方安装文档 地址&#xff1a;https://neo4j.com/docs/operations-manual/current/installation/linux/tarball/ 2.如果浏览器无法访问 修改neo4j.conf,开放所有ip访问 # 允许所有IP地址访问 server.default_listen_address0.0.0.0 3.创建开机自启动服务…

SEO长尾关键词核心实战技巧提升排名

内容概要 本文聚焦于SEO长尾关键词的核心实战技巧&#xff0c;旨在帮助读者精准锁定目标用户的搜索意图&#xff0c;从而提升网站自然排名和获取精准流量。文章将从基础概念入手&#xff0c;系统解析如何挖掘高转化率的长尾关键词&#xff0c;优化内容结构以增强搜索可见度&…

当OT遇见IT:Apache IoTDB如何用“时序空间一体化“技术破解工业物联网数据孤岛困局?

目录 一. 什么是时序数据库&#xff1f; 二. 时序数据库的选型要素 性能指标 架构能力 数据模型与查询能力 安全与权限控制 部署与运维能力 三 Apache IoTDB 简介及安装使用&#xff1a; 安装准备教程 检查 Java 版本 下载与安装 下载 IoTDB 解压文件 配置环境变量 启动…

一文讲透HTML语义化标签

文章目录语义化标签概述HTML标签及其含义常见HTML5语义化标签语义化标签对搜索引擎&#xff08;SEO&#xff09;的影响提升搜索引擎排名增强可访问性改善用户体验语义化标签案例各标签作用说明语义化标签概述 HTML 语义化是指使用恰当的标签来准确表达内容的结构和含义&#x…

Django 实战:静态文件与媒体文件从开发配置到生产部署

文章目录一、静态文件与媒体文件区别与联系配置开发环境配置二、媒体文件实战实战场景定义模型定义序列化器定义视图实战效果三、生产部署说明收集静态文件Nginx配置示例OpenResty配置示例一、静态文件与媒体文件 区别与联系 在 Django 项目中&#xff0c;静态文件&#xff0…

Python自动化分析知网文献:爬取、存储与可视化

1. 引言 在当今的学术研究和大数据分析领域&#xff0c;高效获取和分析学术文献数据具有重要意义。中国知网&#xff08;CNKI&#xff09;作为国内最权威的学术资源平台之一&#xff0c;包含了海量的期刊论文、会议论文和学位论文。然而&#xff0c;手动收集和分析这些数据不仅…

Python应用指南:使用PyKrige包实现ArcGIS的克里金插值法

先了解什么是克里金插值&#xff1f;克里金插值&#xff08;Kriging interpolation&#xff09;是一种基于统计学和空间相关性的高级空间插值方法&#xff0c;广泛应用于地理信息系统&#xff08;GIS&#xff09;、地质勘探、环境科学、气象学等领域。它由南非矿业工程师丹尼尔…

Redis原理之哨兵机制(Sentinel)

上篇文章&#xff1a; Redis原理之主从复制https://blog.csdn.net/sniper_fandc/article/details/149141103?fromshareblogdetail&sharetypeblogdetail&sharerId149141103&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 目录 1 哨兵机制恢…

uniapp打包成 apk

1. 先把项目打包成 index.html 上传到宝塔服务器,关联到域名 2.然后再用hbuilder新建一个 基础模板的 uniapp 3.再修改代码,采用iframe方式打包 pages/index/index <template><web-view v-if="showWebView" :src="webViewSrc" @message=&qu…

RPG57.创建玩家拾取物品类一:创建可拾取物品类的基类

1。新建一个基类&#xff0c;用于玩家可拾取物品的父类然后// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h" #include "Components/SphereComponent.h" #include "GameFramewo…

k8s之持久化存储流程

K8s 中的 Pod 在挂载存储卷时需经历三个的阶段&#xff1a;Provision/Delete&#xff08;创盘/删盘&#xff09;、Attach/Detach&#xff08;挂接/摘除&#xff09;和 Mount/Unmount&#xff08;挂载/卸载&#xff09; Provisioning Volumes 时序流程详解 一、流程图 sequenc…

python学智能算法(二十四)|SVM-最优化几何距离的理解

引言 前序学习过程中&#xff0c;已经对几何距离的概念有了认知&#xff0c;学习链接为&#xff1a;几何距离 这里先来回忆几何距离δ的定义&#xff1a; δmin⁡i1...myi(w∥w∥⋅xib∥w∥)\delta \min_{i1...m}y_{i}(\frac{w}{\left \| w \right \|}\cdot x_{i}\frac{b}{\le…

创建游戏或互动体验:从概念到实现的完整指南

Hi&#xff0c;我是布兰妮甜 &#xff01;在数字时代&#xff0c;游戏和互动体验已成为娱乐、教育和商业领域的重要组成部分。本文将带你了解如何使用JavaScript创建引人入胜的游戏和互动体验&#xff0c;从基础概念到实际实现。 文章目录一、游戏开发基础1.1 游戏循环1.2 游戏…

SpringMVC + Tomcat10

1. Tomcat 10的servlet包路径变了&#xff0c;javax -> jakarta 2. DispatcherServlet从Spring6 才开始使用jakarta.servlet.http.Servlet 3. Spring6 需要JDK 17 1. pom <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org…

Django `transaction.atomic()` 完整使用指南

目录 #概述#基本用法#事务一致性保障机制#破坏一致性的常见场景#高级用法#最佳实践#诊断与调试#附录 概述 transaction.atomic() 是 Django 提供的数据库事务管理工具&#xff0c;用于确保一系列数据库操作要么全部成功提交&#xff0c;要么全部回滚&#xff0c;维护数据的一致…

UDP协议的端口161怎么检测连通性

UDP 端口 161 (SNMP) 连通性检测的专业指南 UDP 161 端口是 SNMP (Simple Network Management Protocol) 服务的标准端口。由于其无连接特性&#xff0c;检测需要特殊方法。以下是全面的检测方案&#xff1a; 一、专业检测方法 1. 使用 SNMP 专用工具&#xff08;推荐&#xff…