数组详解

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

1.1 数组的创建

数组是一组相同类型元素的集合。
数组的创建方式:

type_t arr_name [const_n];
//type_t 是指数组的元素类型
//const_n 是一个常量表达式,用来指定数组的大小

数组创建的实例:

//代码1
int arr1[10];
//代码2
int count = 10;
int arr2[count];//数组时候可以正常创建?
//代码3
char arr3[10];
float arr4[1];
double arr5[20];

注:数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数组的概念。

1.2 数组的初始化

数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。
看代码:

第一种初始化被称为不完全初始化,因为只初始化了一部分,那么剩余的一部分就会默认初始化为0。

第二种初始化则默认这个数组为4个元素。

第三种则是标准的初始化。

第四种是字符数组,可以理解为这个数组里面放了三个字符,98的ASCLL码值为abc。

第五种则是默认3个元素的字符数组。

第六种是使用字符串进行初始化,和第五种的区别在于字符串末尾会有一个\0。

int arr1[10] = {1,2,3};
int arr2[] = {1,2,3,4};
int arr3[5] = {1,2,3,4,5};
char arr4[3] = {'a',98, 'c'};
char arr5[] = {'a','b','c'};
char arr6[] = "abcdef";

数组在创建的时候如果想不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定。
但是对于下面的代码要区分,内存中如何分配。

char arr1[] = "abc";
char arr2[3] = {'a','b','c'};

1.3 一维数组的使用

对于数组的使用我们之前介绍了一个操作符: [] ,下标引用操作符。它其实就数组访问的操作符。
我们来看代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int arr[10] = { 0 };//数组的不完全初始化
	//计算数组的元素个数
	int sz = sizeof(arr) / sizeof(arr[0]);
	//对数组内容赋值,数组是使用下标来访问的,下标从0开始。所以:
	int i = 0;//做下标
	for (i = 0; i < 10; i++)//这里写10,好不好?
	{
		arr[i] = i;
	}
	//输出数组的内容
	for (i = 0; i < 10; ++i)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

需要注意的是下标是从0开始的,所以i<10则是10次。

总结:
1. 数组是使用下标来访问的,下标是从0开始。
2. 数组的大小可以通过计算得到。

int arr[10];
int sz = sizeof(arr)/sizeof(arr[0]);

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

接下来我们探讨数组在内存中的存储。
看代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; ++i)
	{
		printf("&arr[%d] = %p\n", i, &arr[i]);
	}
	return 0;
}

在x86的环境下结果是这样的:

仔细观察输出的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增。为什么差的是4呢?因为一个整形元素是4个字节,每个字节都有一个地址。由此可以得出结论:数组在内存中是连续存放的。

 数组的这种布局是为了内存的访问,因为当我们知道了一个数组的起始位置,往后遍历就能找到后面的所有元素,为使用指针访问数组带来了很大的便利。

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

2.1 二维数组的创建

二维数组相当于存放行和列。

//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];

2.2 二维数组的初始化

第二种初始化相当于{1,2,0,0},{4,5,0,0},{0,0,0,0}。

//数组初始化
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};//二维数组如果有初始化,行可以省略,列不能省略

2.3 二维数组的使用

二维数组的使用也是通过下标的方式。
看代码:

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

  


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

像一维数组一样,这里我们尝试打印二维数组的每个元素。

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

通过结果我们可以分析到,其实二维数组在内存中也是连续存储的,二维数组存储的时候是存完第一行再存第二行。

 3. 数组越界

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

#define _CRT_SECURE_NO_WARNINGS 1
#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\n", arr[i]);//当i等于10的时候,越界访问了
	}
	return 0;
}

 这就属于数组的越界访问了,因为这个数组是10个元素,但是却访问了11次。

4. 数组作为函数参数

往往我们在写代码的时候,会将数组作为参数传个函数,比如:我要实现一个冒泡排序函数,
将一个整形数组排序。

那我们将会这样使用该函数:

4.1 冒泡排序函数的错误设计
 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void sort(int arr[])
{
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (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;
			}
		}
	}
}
//冒泡排序
//降序
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	sort(arr);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

 当我们这样去设计函数,就会发现答案是错误的。

4.2 数组名是什么?

#include <stdio.h>
int main()
{
   int arr[10] = {1,2,3,4,5};
   printf("%p\n", arr);
   printf("%p\n", &arr[0]);
   printf("%d\n", *arr);
   //输出结果
   return 0;
}

数组名是数组首元素的地址。(有两个例外)

1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数
组。
2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。

除此1,2两种情况之外,所有的数组名都表示数组首元素的地址。

4.3 冒泡排序函数的正确设计

当数组传参的时候,实际上只是把数组的首元素的地址传递过去了。
所以即使在函数参数部分写成数组的形式: int arr[] 表示的依然是一个指针: int *arr 。
那么,函数内部的 sizeof(arr) 结果是4。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
	//代码同上面函数
}
int main()
{
	int arr[] = { 3,1,7,5,8,9,0,2,4,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);//是否可以正常排序?
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

这才是正确的冒泡排序函数方法,我们把元素个数作为参数传给函数。

5. 数据实例:

5.1 数组的应用实例1:三子棋

http://t.csdn.cn/OEdsa

5.2 数组的应用实例2:扫雷

http://t.csdn.cn/6NpQq

我的这两篇文章有详解哦,欢迎大家阅读。


今天的分享到这里就结束啦!感谢烙铁们的阅读,让我们下一篇文章再见,下一篇文章会详细的给大家讲解操作符哦!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32 F103C8T6学习笔记8:0.96寸单色OLED显示屏显示字符

使用STM32F103 C8T6 驱动0.96寸单色OLED显示屏: OLED显示屏的驱动&#xff0c;在设计开发中OLED显示屏十分常见&#xff0c;因此今日学习一下。一篇文章从程序到显示都讲通。 文章提供源码、原理解释、测试工程下载&#xff0c;测试效果图展示。 目录 OLED驱动原理—IIC通信…

centos7 部署kubernetes(带自动部署脚本)

目录 一、实验规划 1、规划表 2、安装前宿主机检查 1.配置主机名 2.制作ssh免密&#xff08;VM1中执行&#xff09; 3.修改hosts 文件 4. 修改内核相关参数 5.加载模块 6. 清空iptables、关闭防火墙、关闭交换空间、禁用selinux 7. 安装ipvs与时钟同步 8.配置docker的…

【算法挨揍日记】day03——双指针算法_有效三角形的个数、和为s的两个数字

611. 有效三角形的个数 611. 有效三角形的个数https://leetcode.cn/problems/valid-triangle-number/ 题目描述&#xff1a; 给定一个包含非负整数的数组 nums &#xff0c;返回其中可以组成三角形三条边的三元组个数。 解题思路&#xff1a; 本题是一个关于三角形是否能成立…

【数仓建设系列之一】什么是数据仓库?

一、什么是数据仓库&#xff1f; 数据仓库(Data Warehouse&#xff0c;简称DW)简单来讲&#xff0c;它是一个存储和管理大量结构化和非结构化数据的存储集合&#xff0c;它以主题为向导&#xff0c;通过整合来自不同数据源下的数据(比如各业务数据&#xff0c;日志文件数据等)…

Azure使用CLI创建VM

使用CLI创建VM之前&#xff0c;确保资源中的IP资源已经释放掉了&#xff0c;避免创建的过程中没有可以利用的公共IP地址打开 cloudshell ,并输入创建CLI的命令如下&#xff0c;-n指定名称&#xff0c;-g指定资源组&#xff0c;image指定镜像&#xff0c;admin-usernam指定用户名…

C++音乐播放系统

C音乐播放系统 音乐的好处c发出声音乐谱与赫兹对照把歌打到c上 学习c的同学们都知道&#xff0c;c是一个一本正经的编程语言&#xff0c;因该没有人用它来做游戏、做病毒、做…做…做音乐播放系统吧&#xff01;&#xff01; 音乐的好处 提升情绪&#xff1a;音乐能够影响我们…

Spring Framework中的Bean生命周期

目录 一.Bean生命周期的简介 1.基本概念 2.Spring生命周期的几大阶段 3.注意点及小结 4.生活案例 5.Spring容器管理JavaBean的初始化过程 二. Bean的单例选择与多例选择 1.单例选择与多例选择的优缺点 1.1单例模式的优点&#xff1a; 1.2单例模式的缺点&#xff1a; 1…

insightface安装过程中提示 Microsoft Visual C++ 14.0 or greater is required.

pip install insightface安装过程中提示 Microsoft Visual C 14.0 or greater is required.Get it with "Microsoft C Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/ 根据提示网站访问官网下载生成工具 打开软件后会自动更新环境&#…

Ceph入门到精通-Aws Iam(user,role,group,policy,resource)架构图和快速入门

-- Aws Iam(identity,user,role,group,policy,resource,)架构图和快速入门. 【官网】&#xff1a;Cloud Computing Services - Amazon Web Services (AWS) 应用场景 aws 云服务运维,devops过程中经常涉及各项服务&#xff0c;权限&#xff0c;角色的处理。 为了更好的使用各项…

leetcode 279. 完全平方数

2023.8.18 与零钱兑换相似&#xff0c;本题属于完全背包问题&#xff1a;完全平方数为物品&#xff0c;整数n为背包。 直接上代码&#xff1a; class Solution { public:int numSquares(int n) {vector<int> dp(n1 , INT_MAX);dp[0] 0;for(int i1; i*i<n; i){for(in…

BIO、NIO和AIO

一.引言 何为IO 涉及计算机核心(CPU和内存)与其他设备间数据迁移的过程&#xff0c;就是I/O。数据输入到计算机内存的过程即输入&#xff0c;反之输出到外部存储&#xff08;比如数据库&#xff0c;文件&#xff0c;远程主机&#xff09;的过程即输出。 I/O 描述了计算机系统…

AMD fTPM RNG的BUG使得Linus Torvalds不满

导读因为在 Ryzen 系统上对内核造成了困扰&#xff0c;Linus Torvalds 最近在邮件列表中表达了对 AMD fTPM 硬件随机数生成器的不满&#xff0c;并提出了禁用该功能的建议。 因为在 Ryzen 系统上对内核造成了困扰&#xff0c;Linus Torvalds 最近在邮件列表中表达了对 AMD fTPM…

原生js获取今天、昨天、近7天的时间(年月日时分秒)

有的时候我们需要将今天,昨天,近7天的时间(年月日时分秒)作为参数传递给后端,如下图: 那怎么生成这些时间呢?如下代码里,在methods里的toDay方法、yesterDay方法、weekDay方法分别用于生成今天、昨天和近7天的时间: <template><div class="box"&…

【校招VIP】测试方案之测试用例分析

考点介绍 测试用例是测试岗面试和工作后的核心&#xff0c;在面试里对测试用例的分析是高频考查点。但是很多同学因为没有真实的商业产品需求&#xff0c;只能简单的看别人的用例学习&#xff0c;导致面试时被一个陌生问题卡住。 比如最简单的用户名密码输入&#xff0c;在商业…

⛳ Docker - Centos 安装配置

目录 ⛳ Docker - Centos 安装配置&#x1f3ed; Docker 安装&#xff1a;&#x1f4e2; 一、安装依赖包&#x1f4ac; 二、添加 Docker 下载源地址&#x1f43e; 三、更新yum缓存&#x1f463; 四、安装Docker&#x1f4bb; 五、启动Docker&#x1f381; 六、查看Docker状态和…

vue3 + antv/x6 实现拖拽侧边栏节点到画布

前篇&#xff1a;vue3ts使用antv/x6 自定义节点 前篇&#xff1a;vue3antv x6自定义节点样式 1、创建侧边栏 用antd的menu来做侧边栏 npm i --save ant-design-vue4.x//入口文件main.js内 import Antd from ant-design-vue; import App from ./App; import ant-design-vue/…

OpenFOAM的fvOptions

采用OpenFoam中的fvOptions /*--------------------------------*- C -*----------------------------------*\ |\\ / F ield | OpenFOAM: The Open Source CFD Toolbox\\ / O peration | Website: https://openfoam.org\\ / A n…

安卓框架中的常见问题汇总

目录 1.安卓操作系统的组件结构图如下 2.问题汇总 1.安卓操作系统的组件结构图如下 2.问题汇总 问题1&#xff1a;安卓框架中的库和应用程序框架之间什么关系&#xff1f; 在安卓系统中&#xff0c;应用程序框架层&#xff08;Application Framework&#xff09;是核心应用程…

ADC静态特性测试

测试环境搭建&#xff1a; 码密度分析法的局限性 更新&#xff1a; MATLAB R2020a之后的版本&#xff0c;更新了函数 “inldnl()”&#xff0c;可以自动计算INL和DNL。具体用法看MATLAB说明文档即可。

【FAQ】调用视频汇聚平台EasyCVR的iframe地址,视频无法播放的原因排查

有用户反馈&#xff0c;在调用iframe地址后嵌入用户自己的前端页面&#xff0c;视频无法播放并且要求登录。 安防监控视频汇聚平台EasyCVR基于云边端一体化架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;可提供视频监控直播、云端录像、视频云存储、视频集中…