C语言数组介绍

news2024/9/23 15:33:07

文章目录

  • 一、数组的概念
  • 二、一维数组
    • 1.一维数组的创建
    • 2.一维数组的初始化
    • 3.数组的类型
    • 4.一维数组的使用
    • 5.一维数组在内存中的存储
    • 6.sizeof计算数组元素个数
  • 三、二维数组
    • 1.二维数组的概念
    • 2.二维数组的创建
    • 3.二维数组的初始化
    • 4.二维数组的使用
    • 5.二维数组的输入和输出
    • 6.二维数组在内存中的存储
    • 7.二维数组中对于数组名的理解

一、数组的概念

数组一组相同类型元素的集合;从这个概念中我们就可以发现2个有价值的信息:
数组中存放的是1个或者多个数据,但是数组元素个数不能为0。
数组中存放的多个数据,类型是相同的。
数组分为一维数组和多维数组,多维数组一般比较常见的是二维数组。

二、一维数组

1.一维数组的创建

一维数组创建的语法如下:
在这里插入图片描述存放在数组中的值被称为数组的元素,数组在创建的时候可以指定数组的大小和数组的元素类型。
type指定的是数组中存放的数据的类型,可以是: char、short、int、float等,也可以自定义的类型。
arr_name指的是数组的名字,这个名字根据实际情况,起的有意义就行。(注意不要跟关键字重名)
[ ]中的常量值是用来指定数组的大小的(元素个数),数组的大小根据实际的需求指定就行。
需要注意在创建数组时,[ ]中要给的是一个常量才可以,不能给变量。[ ]可以直接使用常量,常量表达式或者宏定义都可以。示例:

#include<stdio.h>
#define NUM 6
int main()
{
    int arr1[10];
    int arr2[2+3];
    char ch[NUM];
    return 0;
}

2.一维数组的初始化

在创建数组的同时,给一些初始值,这种就称为数组的初始化。那数组如何初始化呢?数组的初始化一般使用大括号,将数据放在大括号中:

//完全初始化
int arr1[5]={1,2,3,4,5};

//不完全初始化
int arr2[5]={1};//第一个元素初始化为1,剩下的元素默认初始化为0

3.数组的类型

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

int arr[10];
char ch[5];

arr数组的类型为int [10],ch数组的类型为char [5]。

4.一维数组的使用

学习了一维数组的基本语法,一维数组可以存放数据,存放数据的目的是对数据进行操作,那我们如何使用一维数组呢?
(1)数组下标
C语言规定数组是有下标的,下标是从0开始的,假设数组有n个元素,最后一个元素的下标是n-1,下标就相当于数组元素的编号,如下:

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

在这里插入图片描述在C语言中,对于数组的访问提供了一个操作符 [ ],这个操作符叫:下标引用操作符
有了下标引用操作符,我们就可以轻松的访问到数组的元素了,比如我们访问下标为6的元素,我们就可以使用arr[6],想要访问下标是4的元素,就可以使用arr[4],如下代码:

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

运行结果:
在这里插入图片描述(2)数组元素的打印
如果想要打印数组的元素在屏幕上,就用for循环产生0~9的下标,使用下标访问数组的元素即可:

#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;
}

运行结果:
在这里插入图片描述(3)数组元素的输入
可以根据自己的需要,用scanf函数给数组输入值,存入到数组中。给数组输入想要的数据:

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	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;
}

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

5.一维数组在内存中的存储

一维数组在内存中是怎样存储的呢?我们通过下面一段代码来看:

#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("&arr[%d]=%p\n",i, &arr[i]);
	}
	return 0;
}

运行结果:
在这里插入图片描述从输出的结果可以发现,数组随着下标的增长,地址是由小到大变化的,并且我们发现每相邻两个元素之间相差4(因为一个整型是4个字节)。所以我们得出结论:数组在内存中是连续存放的

6.sizeof计算数组元素个数

在遍历数组的时候,我们经常想知道数组的元素个数,那C语言中有办法使用程序计算数组元素个数吗?答案是有的。通过sizeof可以求元素个数。其实sizeof是一个操作符,是用来计算类型或者变量的大小的(单位字节)。sizeof可以用来计算数组的大小:

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

运行结果:
在这里插入图片描述输出的结果为40,计算的是整个数组所占内存空间的大小,单位是字节(数组名单独放在sizeof中,计算的是整个数组的大小)。又因为数组中所有元素的类型是相同的,所以只要计算出一个元素所占字节的个数,那数组的元素个数就可以计算出来了。我们通常选择计算第一个元素的大小:

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	//计算数组中第一个元素的大小
	printf("%d\n", sizeof(arr[0]));

	//计算数组的元素个数
	int sz = sizeof(arr) / sizeof(arr[0]);
	printf("%d\n", sz);
	return 0;
}

运行结果:
在这里插入图片描述可以看到,第一个元素的大小为4(字节),数组的元素个数为10。以后在代码中需要数组元素个数的地方就不用固定写死了,这种计算数组元素个数的方式,不管数组怎么变化,计算出的大小也会随着变化。

三、二维数组

1.二维数组的概念

上面学习的数组叫一维数组,数组的元素都是内置类型的。如果把一维数组做为数组的元素,这时候就是二维数组。二维数组作为数组元素的数组被称为三维数组,二维数组以上的数组统称为多维数组
在这里插入图片描述

2.二维数组的创建

如何创建二维数组呢?语法形式是什么?如下:
在这里插入图片描述例如:

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

上面代码的第一行,就是一个整型的二维数组。其中:
3表示有3行;5表示列数,即每一行有5个元素。
int表示数组的每个元素是整型类型。
arr是数组名,可以根据自己的需要指定名字(注意不能和关键字重名)。
第二行是一个双精度浮点型二维数组。

3.二维数组的初始化

在创建数组的同时,给一些初始值,就叫数组的初始化。二维数组的初始化也跟一维数组类似,使用大括号初始化:
(1)不完全初始化

int arr1[3][5]={1,2};
int arr2[3][5]={0};

在屏幕上打印这两个数组:
在这里插入图片描述可以看到上面对于两个二维数组不完全初始化的打印结果,对于arr1数组,只初始化了两个元素,即从第一行的一维数组的第一个元素开始,从左往右依次初始化。如果一行的元素值给够了,就会从下一行一维数组的第一个元素开始从左往右初始化。对于没有给到值的元素会默认初始化为0。arr2数组只初始化了第一行的第一个元素为0,其余元素默认初始化为0。如下:
在这里插入图片描述(2)完全初始化

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

在屏幕上打印arr3数组的内容:
在这里插入图片描述完全初始化就很好理解了:在创建二维数组的同时,对二维数组的所有元素都给一个初始值,就叫作完全初始化,对于{ }里的值,会从左往右,依次给到二维数组对应的元素。如果一行的值够了,就会从数组下一行的一维数组的第一个元素开始从左往右初始化。
(3)按照行进行初始化
什么叫按照行进行初始化?其实就是按照二维数组的每个一维数组进行初始化,在二维数组的大括号{ }内部,会明确的给出每个一维数组,对每个一维数组进行初始化。例如:

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

打印出数组的内容,如下图样式:
在这里插入图片描述可以看到上面的二维数组按照行进行初始化,在大括号的内部明确给出了二维数组的每个一维数组,因为一维数组的内容也是用大括号括起来的。所以在二维数组里对每一行进行初始化是遵循一维数组的初始化原则的。
(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}};

上面三个数组得到数组形式会是:
在这里插入图片描述可以看到当数组给出列数却没有给出行数时,系统会根据你大括号里初始化数据的多少,自动计算数组的行数,确定数组是一个什么类型的数组。

4.二维数组的使用

二维数组的访问也是使用下标的形式进行的,二维数组是有行和列的,只要锁定了行和列就能唯一锁定数组中的一个元素。C语言规定:二维数组的行是从0开始的,列也是从0开始的,如下所示:

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

在这里插入图片描述上图中,最左侧的灰色数字表示行号,最上面一行的橙色数字表示列号,可以发现下标都是从0开始。比如:行号为2,列号为3的元素,就是6:

#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][3]);
    return 0;
}

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

5.二维数组的输入和输出

上面讲过一维数组的访问,是通过下标进行的,用for循环产生对应的下标。二维数组也是一样的,也是通过下标来访问,只不过二维数组有行和列两个下标,如果要对二维数组进行输入输出的话,就要使用两个for循环,外层循环控制每一行的循环,内层的循环控制每一行里所有元素个数(列数)的循环。比如我们要输入和打印上面的arr数组在屏幕上,行的范围是0~2,列的范围是0~4,用两个for循环产生相应的行和列号:

#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]); //输入数据
		}
	}
	//输出
	for (i = 0; i < 3; i++) //产生行号
	{
		int j = 0;
		for (j = 0; j < 5; j++) //产生列号
		{
			printf("%d ", arr[i][j]); //输出数据
		}
		printf("\n");
	}
	return 0;
}

输入数据后得到的结果:
在这里插入图片描述

6.二维数组在内存中的存储

与一维数组一样,如果想知道二维数组在内存中的存储方式,我们也是可以打印出数组所有元素的地址的。代码如下:

#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个字节,跨行位置处的两个元素(如: arr[0][4]和arr[1][0])之间也是差4个字节,所以得到的结论是:二维数组中的每个元素在内存中都是连续存放的

7.二维数组中对于数组名的理解

在二维数组中,数组名表示什么含义?我们之前讲过一维数组的数组名是表示数组首元素的地址,也就是数组中第一个元素的地址。那二维数组的数组名其实也表示数组首元素的地址,但是这个首元素是指那个呢?这里我们要把二维数组看成是一个一维数组。举个例子:

int arr[3][4]={0};

在这里插入图片描述二维数组其实可以看作是由一维数组构成的数组,也就是把每行的一维数组整体看做是一个元素,则二维数组现在就相当于一个一维数组,数组的首元素就是第一行的一维数组,则数组名就是第一行一维数组的地址,它是一个数组指针。就像上面的arr[3][4]数组,数组名arr表示的是第一行一维数组的地址,它是一个 int(*)[4] 类型的数组指针:即 arr==&arr[0]

二维数组去掉列下标部分也是数组名,如下:
在这里插入图片描述数组名表示的是数组首元素的地址。则二维数组去掉列下标后的数组名,如上面的arr[0]、arr[1]和arr[2]分别表示二维数组中每行一维数组的首元素地址,即每个一维数组的第一个元素的地址,类型是int*的指针:arr[0]==&arr[0][0]arr[1]==&arr[1][0]arr[2]==&arr[2][0]
所以在二维数组中要区分开上面的两种数组名,不能混淆,尤其是在sizeof中放有关数组名的各种表达式时,要特别区分上面的两种数组名。

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

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

相关文章

Linux主机重启后报错:[FAILED] Failed to start Switch Root.

一、问题描述 某次云主机因计费问题&#xff0c;导致批量重启&#xff0c;重启后发现某台云主机竟进入紧急救援模式&#xff08;emergency模式&#xff09;&#xff0c;如下所示&#xff1a; 二、原因及处理 1&#xff09;原因&#xff1a;加载根分区失败&#xff0c;导致无…

文字转语音软件下载教程

文字转语音软件下载教程 一&#xff0c;Whisper下载二&#xff0c;ggml-medium语言模型下载三&#xff0c;导入模型下载四&#xff0c;使用方法 一&#xff0c;Whisper下载 网址&#xff1a;https://bittly.cc/uL9xs 下拉选择&#xff1a; 进入下载页面&#xff0c;下载Whis…

笔记:编写程序,绘制一个展示支付宝月账单报告的饼图

文章目录 前言一、饼图是什么&#xff1f;二、编写代码总结 前言 笔记&#xff1a;编写程序&#xff0c;绘制一个展示支付宝月账单报告的饼图 &#xff08;1&#xff09; 导入 matplotlib.pyplot 模块&#xff1b; &#xff08;2&#xff09; 准备饼图所需的数据&#xff1b; …

【设计模式】创建者模式之 工厂方法 抽象工厂

工厂方法模式(Factory Method) 一个特定功能&#xff0c;往往有多种实现方式&#xff0c;但是很难有某一个实现可以适用于所有情况&#xff0c;因此往往需要根据特定的场景选择不同的实现。试想&#xff1a;把选择具体实现的代码放在业务中会发生什么&#xff1f;每当我们需要…

压缩png图片大小怎么操作?试试这招一键压缩图片体积

png图片是一种无损压缩格式&#xff0c;体积也会比其他格式的图片要大。但是&#xff0c;我们在使用的过程中遇到需要给png图片压缩体积的情况时要怎么办呢&#xff1f;很简单&#xff0c;只需要使用png压缩大小&#xff08;https://www.yasuotu.com/png&#xff09;网站-压缩图…

SuperMap GIS基础产品FAQ集锦(20240429)

一、SuperMap iServer 问题1&#xff1a;咨询一下&#xff0c;正式许可插上后&#xff0c;出现这样的提示。可能是哪方面的原因呢&#xff1f; 11.1.1 【问题原因】虚拟机环境读取USB设别需要设置USB映射 【解决办法】虚拟平台重新进行USB映射操作后能正常读取许可 问题2&a…

【数字图像处理笔记】Matlab实现图像平滑算法 均值-中值-高斯滤波 (三)

&#x1f48c; 所属专栏&#xff1a;【数字图像处理笔记】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x…

Obsidium v1.5.4壳 逆向分析

样本是使用这个壳进行打包的 来进行逆向 进入X32 DBG中 进来一看就是经典花指令 混淆解析器 可以在CE中查找指令地址 来得到当前真正执行的指令 对SEH链进行劫持 马上就来个int 1进入异常处理函数 无视异常 直接进去 观察Zwcontinue函数传进去的Context结构体 结构体偏移…

HFP event

0 Preface/Foreword NOTE&#xff1a;在来电提示音在响时候&#xff0c;每3s会进入一次。 也就是说&#xff1a;协议栈&#xff0c;没3s会调用一次app_hfp_event_callback。 回调函数在hfp初始化时候通过btif_hf_register_callback注册。 提示音调节&#xff1a; iPhone6s iO…

Leetcode编程练习

面试题-消失的数字 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:void reverse(vector<int>& nums, int start, int end) {while (start < end) {swap(nums[start], nums[end]);start 1;end - 1;}}void rotate(vector<int>& …

IPD-开发流程

2024-5-6记录于PR办公室 在上一家公司做硬件产品经理的时候&#xff0c;Richard Li曾花费“巨资”请了华为前战略专家给我们培训&#xff0c;讲授IPD这门课的模式都很IPD&#xff0c;当时完全没重视&#xff0c;光想着不可能靠这个能把产品做好&#xff0c;这样做产品必定是一批…

RS2057XH功能和参数介绍及规格书

RS2057XH 是一款由润石科技&#xff08;Runic Semiconductor&#xff09;生产的模拟开关芯片&#xff0c;其主要功能和参数如下&#xff1a; 产品特点&#xff1a; 低电压操作&#xff1a;支持低至1.8V的工作电压&#xff0c;适用于低功耗应用。 高带宽&#xff1a;具有300MHz的…

Matlab 手写板设计

1、介绍 MATLAB手写板可以作为一个很好的数据输入口&#xff0c;其可以获取该手写板上任意字母、数字&#xff0c;甚至可以制作样本数据。具体用途体现在如下几方面&#xff1a; 数学公式输入&#xff1a;手写板允许用户直接用手写方式输入复杂的数学公式&#xff0c;这对于使…

C/C++ BM32 合并二叉树

文章目录 前言题目解决方案一1.1 思路阐述1.2 源码 解决方案二2.1 思路阐述2.2 源码 总结 前言 树的题目大概率是要用到递归的&#xff0c;将一个树的问题拆分成子树的问题&#xff0c;不断拆分。 这题也用到了递归的思想。 题目 已知两颗二叉树&#xff0c;将它们合并成一颗…

基于springboot+vue+Mysql的租房网站

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

Java17 --- SpringCloud之Nacos

目录 一、下载nacos并运行 1.1、创建9001微服务作为提供者 1.2、创建80微服务作为消费者 二、naocs配置中心规则与动态刷新 2.1、创建3377微服务 2.2、在nacos中创建配置文件 三、nacos数据模型之Namespace-Group-Datald 3.1、DatalD方案 3.2、Group方案 3.3、Name…

产业观察:电机驱动成为人形机器人的动力核心

前不久&#xff0c;波士顿动力发布一则“再见&#xff0c;液压Atlas”视频&#xff0c;宣告其著名的液压驱动双足人形机器人Atlas正式退役。这则视频引起全球所有Atlas粉丝的高度关注。然而紧接着&#xff0c;波士顿动力便又推出了全部由电机驱动的新一代Atlas机器人&#xff0…

数据结构相关

数据结构相关 文章目录 数据结构相关[TOC](文章目录)前言一、数据结构介绍二、不同的逻辑结构的存储方案(Java实现)2.1 线性结构&#xff1a;线性表、数组2.2 线性结构&#xff1a;栈2.3 线性结构&#xff1a;队列2.4 树形结构&#xff1a;树 三、一些常见的3.1 布隆过滤器Bloo…

自动化工具

一、介绍一些自动化的工具 puppet和chef用的是Ruby语言http协议&#xff0c;淘汰 saltstack Python语言 c/s ssh协议&#xff0c;5% ansible 无cilent ssh协议 用Python开发 95% 二、ansible简介 2.1 ansible自动化运维工具特点 Ansible 与 Saltstack 均是基于…

Day_1

1. 环境搭建 技术选型 后端项目结构 sky-take-out maven父工程&#xff0c;统一管理依赖版本&#xff0c;聚合其他子模块 sky-common 子模块&#xff0c;存放公共类&#xff0c;例如&#xff1a;工具类、常量类、异常类等 sky-pojo 子模块&#xff0c;存放实体类、VO、DTO…