C语言数组

文章目录

    • 1:一维数组的创建和初始化
      • 1.1 创建方式
      • 1.2:一维数组的初始化
      • 1.3:一维数组的使用
        • 1.3.1:数组下标
      • 1.4:一维数组在内存中的存储
    • 2:二维数组的创建和初始化
      • 2.1:二维数组的创建
      • 2.2:二维数组的初始化
      • 2.3:二维数组的下标
      • 2.4:二维数组在内存中的存储
    • 3:数组越界
    • 4:数组名
    • 5:冒泡排序

嘿嘿,家人们,今天咱们来详细介绍下C语言中的数组,好啦,废话不多讲,开干!

1:一维数组的创建和初始化

概念:数组是指一组**相同类型元素**的集合。

从这个概念中,我们可以知道以下两个信息:
(1):数组中存放的是1个或多个数据,但是数组的元素个数不能为0。
(2):数组中存放的多个数据,其数据类型是相同的。
数组分为一维数组和多维数组,多维数组一般比较常见的是二维数组。

1.1 创建方式

type_t arr_name [const_n]
//type_t 指数组的元素类型
//const_n 为一个常量表达式用于指定数组的大小
//[]中的常量值是用于指定数组的大小,这个数组的大小要根据实际的需求来进行指定。

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr1[5];int arr2[3 + 2];int n = 0;scanf("%d\n",&n);//变长数组char arr3[n];return 0;
}

PS:在创建数组时,我们通常使用一个常量表达式用于指定数组的大小,而不是变量,原因在于,在c99之前数组只能是常量指定大小,在C99之后引入了变长数组的概念,数组的大小是可以使用变量来指定滴。博主使用的vs2022是不支持变长数组滴,希望uu们注意。

在这里插入图片描述

1.2:一维数组的初始化

有时候,数组在创建的时候,我们需要给定一些初始值,这种操作就被称作初始化。那么如何对数组进行初始化呢?数组的初始化一般使用大括号,将数据放在大括号中。
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{//完全初始化int arr1[5] = { 1,2,3,4,5 };//不完全初始化,第一个元素初始化为1,剩余的元素默认初始化为0int arr2[8] = { 1 };//未指定大小,则根据数组中元素的值来确定数组的元素个数int arr3[] ={1,2,3,4,5};//错误的初始化----初始化项太多,超过了数组的元素个数int arr4[3] = {1,2,3,4};return 0;
}

在这里插入图片描述

1.3:一维数组的使用

学习了⼀维数组的基本语法,⼀维数组可以存放数据,存放数据的⽬的是对数据的操作,那我们如何使⽤⼀维数组呢?
1.3.1:数组下标

C语言规定数组中的每个元素是有对应的下标的,下标是从0开始的,假设数组有n个元素,最后一个元素的下标识n-1,下标就相当于数组元素的标号。

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };return 0;
}

在这里插入图片描述

在C语言中数组的访问提供了一个操作符[],这个操作符叫:下标引用操作符有了下标访问操作符,我们就可以轻松地访问到数组的元素了,譬如我们想访问下标为7的元素,就可以使用arr[7],访问下标为3的元素,可以使用arr[3]。

#define  _CRT_SECURE_NO_WARNINGS
#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.4:一维数组在内存中的存储

有了前面的知识,我们其实使用数组基本上没有什么障碍了,如果想要深入了解数组,我们最好能了解一下数组在内存中的存储。 接下来我们将使用如下代码来打印数组在内存中的存储。

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };for (int i = 0; i < 10; i++){//%p用于打印指针的值,将地址以16进制的形式输出printf("&arr[%d] = %p\n", i, &arr[i]);}return 0;
}

在这里插入图片描述

从输出的结果我们可以发现,数组随着下标的增长,地址是由小到大变化的,并且每两个相邻的元素之间相差4(因为一个整型占4个字节)。因此,我们可以得出这样一个结论:数组在内存中是连续存储的,并且随着下标的增长,地址是由低到高变化的,从低地址到高地址

2:二维数组的创建和初始化

概念:前面博主所讲的数组被称作一维数组,数组的元素类型都是内置类型的,如果我们把一维数组作为数组的元素,这个时候为**二维数组**,二维数组作为数组元素的数组被称为**三维数组**,二维数组以上的数组统称为**多维数组**。

PS:二维数组可以与我们在大学中线性代数中的矩阵进行类比哦

2.1:二维数组的创建

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

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{//3表示数组有3行,5表示每一行有5个元素,即3行5列int arr1[3][5];double arr2[2][8];return 0;
}

2.2:二维数组的初始化

二维数组的初始化,和一维数组一样,也是使用大括号初始化滴!
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{//不完全初始化int arr1[3][5] = { 1,2 };int arr2[3][5] = { 0 };//完全初始化int arr3[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };return 0;
}

在这里插入图片描述

ps:二维数组在初始化时,行可以省略,但是列不能够省略,当行省略时,则是根据数组中的元素的值来确定行。

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

在这里插入图片描述

2.3:二维数组的下标

当我们掌握了二维数组的创建与初始化后,那我们怎么样去使用二维数组呢?其实二维数组的访问也是通过下标的形式去访问的,二维数组是有行和列的,只要锁定了行和列就能唯一锁定数组中的一个元素。
C语言规定,二维数组的行是从0开始的,列也是从0开始的。

在这里插入图片描述

通过这段代码实现了对二维数组的访问,只要我们能够按照一定的规定产生所有的行和列,就能够实现对二维数组的访问。

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

和一维数组一样,如果想研究二维数组在内存中的存储方式,我们也是可以打印出数组所有元素的地址滴。
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };//锁定行for (int i = 0; i < 3; i++){//锁定列for (int j = 0; j < 5; j++){printf("&arr[%d][%d] = %p ",i,j,&arr[i][j]);printf("\n");}printf("\n");}return 0;
}

在这里插入图片描述

从输出的结果来看,每一行的内部的每个元素都是相邻的,地址之间相差4个字节,跨行位置的两个元素(如:arr[1][4]和arr[2][0])之间也是差4个字节,因此二维数组中的每个元素都是连续存放的。如下图所示

在这里插入图片描述

3:数组越界

数组的下标是有范围限制的。
数组的下标规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。
因此数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组的合法空间的访问。
ps:C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的。
因此在写代码时,最好自己做越界的检查。

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

在这里插入图片描述

4:数组名

什么是数组名呢?博主将通过下面这段代码来讲解数组名
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5 };printf("  arr   = %p\n", arr);printf("&arr[0] = %p\n", &arr[0]);printf(" *arr   = %d\n", *arr);return 0;
}

在这里插入图片描述

通过这段代码的运行结果我们可以得出,数组名表示数组首元素的地址。OK,如果数组名为首元素的地址,那么再看下面这段代码。

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

在这里插入图片描述

不是说数组名为首元素的地址吗,那这里为什么输出的是40呢?
> 补充:(1):sizeof(数组名),计算的是整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组。
(2):&数组名,取出的是整个数组的地址。&数组名,数组名表示整个数组。
除了这两种特殊情况,在其他情况,所有的数组名均表示数组首元素的地址。

5:冒泡排序

有了我们数组以及函数等等的相关知识,接下来博主将为uu们介绍一种排序算法----->冒泡排序。这里博主以排成升序为例。

核心思想:两两相邻元素进行比较。
请添加图片描述

我们通过上面的动图可以发现,每进行一趟冒泡排序,就可以让元素到达自己应该处的位置。假设我们要对10个数进行排序,那么应该要进行几趟冒泡排序呢?答案应该是9趟,因为单独的一个数我们可以认为它是有序滴,这里家人们要注意哈。首先我们来看单趟的冒泡排序

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };//求出数组中的元素个数int sz = sizeof(arr) / sizeof(arr[0]);for (int j = 0; j < sz - 1; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;} }return 0;
}

如果左边的元素大于右边的元素,那么这两个数就进行交换,直到该元素到达自己应该所处的位置,这是一趟冒泡排序,但是这里有10个数呀,要进行9趟冒泡排序,并且每次进行一趟冒泡排序后,趟数要减少,因此就要使用双层的嵌套循环来进行实现!

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };//求出数组中的元素个数int sz = sizeof(arr) / sizeof(arr[0]);printf("排序前:>");for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}//确定总趟数for (int i = 0; i < sz - 1; i++){//每进行一次冒泡排序,趟数要减少,因此- ifor (int j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}printf("\n");printf("排序后:>");for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

在这里插入图片描述

好啦,家人们,关数组这块的相关细节知识,博主就讲到这里了,如果uu们觉得博主讲的不错的话,请动动你们滴滴给博主点个赞,你们滴鼓励将成为博主源源不断滴动力!

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

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

相关文章

request entity too large 解决请求实体过大问题的方法

在网络请求过程中&#xff0c;有时会出现请求实体过大而导致服务器无法处理的情况。本文将介绍两种情况及其解决办法&#xff0c;真实可用&#xff01; 问题描述 请求实体过大问题主要分为两种情况&#xff1a; 1、带413状态码的请求实体过大 这种情况通常发生在请求文件过…

display布局实现一侧的盒子高度与另一侧盒子的高度等高

实现两边容器的高度等高主要是用 align-items: stretch 这个属性 stretch 拉伸: 子元素没有高度或高度为auto&#xff0c;将占满整个容器的高度 <template><div><h3>我是测试页面</h3><div class"container"><div class"left-…

09、Kafka ------ 通过修改保存时间来删除消息(retention.ms 配置)

目录 通过修改保存时间来删除消息★ 删除指定主题的消息演示1、修改kafka检查过期消息的时间间隔2、修改主题下消息的过期时间3、查看修改是否生效4、先查看下主题下有没有消息5、添加几条消息看效果6、查看消息是否被删除 ★ 恢复主题的retention.ms配置1、先查看没修改前的te…

常见半导体设备厂商介绍

半导体作为全球最重要的一个产业&#xff0c;每年为全球经济贡献数千亿美元产值。在整个产业链上&#xff0c;除我们耳熟能详的英特尔、AMD、高通、台积电等生产商外&#xff0c;还包括了众多著名的材料商和设备商。今天我们将对全球最为出色的半导体设备厂商进行一次盘点和介绍…

学习c语言,奇偶排序

如果左边是奇数右边是偶数就不管他&#xff0c;如果左边找到偶数右边是奇数则互相交换。

【大厂算法面试冲刺班】day0:数据范围反推时间复杂度

常见算法的时间复杂度 规定n是数组的长度/树或图的节点数 二分查找&#xff1a;O(logn) 双指针/滑动窗口&#xff1a;O(n) DFS/BFS&#xff1a;O(n) 构建前缀和&#xff1a;O(n) 查找前缀和&#xff1a;O(1) 一维动态规划&#xff1a;O(n) 二维动态规划&#xff1a;O(n^2) 回溯…

图像表示方法

RGB表示 RGB是使用三基色合成的原理&#xff0c;我们看到的彩色图片&#xff0c;都有三个通道&#xff0c;分别为红、绿、蓝通道&#xff0c;如果需要透明度则还有alpha分量. 通常每个通道用8bit表示&#xff0c;8bit能表示256种颜色&#xff0c;所以可以组成 256256256167772…

云服务器搭建GitLab

经验总结&#xff1a; 1、配置需求&#xff1a;云服务器内存最低4G 2、内存4G的云服务器&#xff0c;在运行容器后&#xff0c;会遇到云服务器操作卡顿问题&#xff0c;这里有解决方案 转载&#xff1a;服务器搭建Gitlab卡顿解决办法-CSDN博客 3、云服务器的操作系统会影响…

游戏开发,中小公司跳槽去大厂容易还是考研应届生校招容易?

游戏开发&#xff0c;中小公司跳槽去大厂容易还是考研应届生校招容易&#xff1f; 在之前的文章中&#xff0c;我们提到过&#xff0c;游戏开发行业首选直接进入游戏大厂。《开发者必读&#xff1a;如何选择适合的游戏开发公司&#xff1f;》因为大厂不仅能提供良好的职业发展…

#AIGC##LLM##RAG# RAG:专补LLMs短板_减少LLM幻觉并多模态/RAG 技术最新进展

RAG技术&#xff0c;即检索增强生成&#xff0c;标志着自然语言处理领域的重大进展。通过整合先前知识&#xff0c;它提升了大型语言模型的性能&#xff0c;广泛应用于多模态领域和垂直行业。本文深入探讨了RAG技术的演进历程、技术发展、LLMs问题及其解决方案&#xff0c;为读…

localStorage、sessionStorage、vuex区别和使用感悟

一、介绍及区别 localStorage的生命周期是永久&#xff1b;不手动在浏览器提供的UI上清除localStorage信息&#xff0c;否则这些信息将永远存在。 sessionStorage的生命周期为当前窗口或标签页&#xff0c;一旦窗口或标签页被永久关闭&#xff0c;那么所有通过sessionStorage存…

[软件工具]AI软件离线表格识别工具使用教程图像转excel转表格可复制文字表格导出实时截图识别成表格

【官方框架地址】 https://github.com/PaddlePaddle/PaddleOCR.git 【算法介绍】 PaddleOCR是一个基于PaddlePaddle框架的开源光学字符识别&#xff08;OCR&#xff09;工具库&#xff0c;由百度公司开发。它提供了一套完整的OCR解决方案&#xff0c;包括文字检测、文字识别以…

中间件框架知识进阶

概述 近期从不同渠道了解到了一些中间件相关的新的知识&#xff0c;记录一下收获。涉及到的中间件包括RPC调用、动态配置中心、MQ、缓存、数据库、限流等&#xff0c;通过对比加深理解&#xff0c;方便实际应用时候更明确如何进行设计和技术选型。 一、RPC框架中间件系列 1、…

JavaWeb后端——Maven

maven主要服务于基于Java平台的项目构建、依赖管理和项目信息管理 maven项目对象模型简称POM&#xff0c; maven解决问题&#xff1a; 1. 添加第三方jar包&#xff0c;maven将 jar 包放在本地仓库中统一管理&#xff0c;使用时用坐标的方式引用即可 2. 解决 jar 包之间的依…

MIT 6s081 lab1:Xv6 and Unix utilities

Lab1: Xv6 and Unix utilities 作业网址&#xff1a;https://pdos.csail.mit.edu/6.828/2020/labs/util.html Boot xv6(easy) 下载&#xff0c;启动xv6系统 $ git clone git://g.csail.mit.edu/xv6-labs-2020 Cloning into xv6-labs-2020... ... $ cd xv6-labs-2020 $ git …

计算机网络——应用层(3)

计算机网络——应用层&#xff08;3&#xff09; 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU) 点对点&#xff08;P2P&#xff09;P2P网络一般用途优点缺点总结 套接字编程基本步骤UDP套接字TCP套接字基本步骤 二者对比 小程一言 我的计算机网络专栏&#xff0c;是自…

基于SSM的高校班级同学录网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

maven导入无法拉取所需依赖

maven导入无法拉取所需依赖 1.原因2.解决搞定收工&#xff01; 1.原因 公司使用的是gradle&#xff0c;配置的私有云&#xff0c;maven里面配置私有云完全使用不了&#xff0c;无论配置国内还是国外的&#xff0c;导入的项目报错拉不到jar包。 <mirror><id>mirro…

倒计时1天|解锁「PolarDB开发者大会」正确打开方式

1月17日 9:30-16:30 北京嘉瑞文化中心 PolarDB开发者大会 明天就要和大家就见面啦&#xff5e; 大会参会指南现已出炉 各位开发者们&#xff0c;请查收~ &#x1f447;&#x1f447;&#x1f447; 点击 大会主页 or 扫描上方二维码 一键抵达大会官网&#x1f447; 查看…

微服务接口工具Swagger2

##1、什么是Swagger? # 官网 https://swagger.io/核心功能 生成接口说明文档生成接口测试工具 2、SpringBoot集成Swagger2 1&#xff09;、添加依赖 <!-- swagger2 --><!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --><depen…