揭秘C语言【数组】的神秘面纱!

本文详细介绍了C语言中一维数组的创建、初始化、使用和内存存储,以及二维数组的概念、创建方式和内存布局。同时讨论了C99中的变长数组特性,强调数组类型、数组元素个数计算和数组特点。
摘要由CSDN通过智能技术生成

在这里插入图片描述

前言

思考题:

一个养鸡场有6只鸡,他们的体重分别是1kg, 3kg, 5kg, 3.4kg,6kg,2kg,请问这6只鸡的总体重是多少?平均体重是多少?

思路分析:

用传统方法:

  • 定义6个double 变量 //但是如果一个养鸡场有600只鸡呢?
  • 统计他们的和,求出平均值
  • 传统的方案不灵活,不能完成数量较大的需求

用数组就会很方便:

  • 数组可以存放多个同一类型的数据,是构造类型,传递是以引用的方式传递(即传递的是地址)

1、一维数组

1.1、一维数组的创建和初始化

数组创建

存放在数组的值被称为数组的元素,数组在创建的时候可以指定数组的大小和数组的元素类型。
例如:

//代码示例:
int math[20];
char ch[8];
double score[10];

有时候,数组在创建的时候,我们需要给定一些初始值,此时就需要对其进行初始化。数组的初始化一般使用大括号,将数据放在大括号中。

数组初始化

另外我们需要知道的是数组也是有类型的,数组算是一种自定义类型。判断方法就是去掉数组名,留下的就是数组类型。
例如:

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

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


1.2、一维数组的使用

我们掌握了一维数组的基本语法后,接下来就要去学习如何去使用数组。

数组下标

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

例如:

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

画图理解
草图
在C语言中为数组的访问提供了一个操作符[ ](下标引用操作符)
我们使用这个下标引用操作符就可以轻松的访问到数组的元素。比如我们访问下标为4的元素,就可以去使用arr[4],得到数组元素5了。

程序验证:
在这里插入图片描述
上面是访问单个数组元素并打印的方式,那如果我们想要打印多个数组元素,该怎么办?其实也很简单,就是使用循环,去访问数组的下标就行了。

在这里插入图片描述

明白了数组的访问,当然我们也需要更加实际情况,自己给数组输入想要的数据,依然是使用数组下标和循环结构去实现。
代码实现:

#include<stdio.h>

int main()
{
	int arr[10] = { 0 };
	for (int i = 0; i < 10; i++)
	{
		scanf("%d", &arr[i]);//输入自己想要的元素。
	}
//------------------------------------------------------
	for (int j = 0; j < 10; j++)
	{
		scanf("%d", arr[j]);//打印数组中的所有元素。
	}
	
	return 0;
}


1.3、一维数组在内存中的存储

数组在内存中是怎样存储的?请看下图分析!
在这里插入图片描述
通过VS的调试,我们可以看到,数组随着下标的增长,地址是由小到大变化的,并且我们发现每两个相邻的元素之间相差4(因为一个整型是4个字节)。所以我们得出结论:数组在内存中是连续存放的


2、二维数组

我们学习了一维数组,我们知道数组的元素都是内置类型的,如果我们把一维数组作为数组的元素,这个时候就是二维数组,二维数组作为数组元素的数组被称为三维数组… …
在这里插入图片描述

2.1、二维数组的创建和初始化

二维数组的创建和初始化跟一维数组差不多。

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

例如:
int arr[3][5]; //int表示数组的每个元素都是整型,3表示数组有3行,5表示每一行有5个元素
char ch[2][8]; //同理


①不完全初始化:

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

在这里插入图片描述

③按照行初始化:

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

在这里插入图片描述

④初始化时可以省略行,但不能省略列:

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.2、二维数组的使用

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

对于二维数组的输入和输出,我们只需要能够按照一定的规律产生所有的行和列的数字,就可以实现对二维数组的输入和输出了。因此,我们同样可以借组循环实现生成数组的下标。

#include<stdio.h>

int main()
{
	int arr[3][5] = { 0 };
	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;
}


2.3、二维数组在内存中的存储

在这里插入图片描述
从数据存储在内存中的结果来看,我们可以看到每一行内部的每个元素都是相邻的,地址之间相差4个字节,跨行位置处的两个元素之间也是差4个字节,所以我们可以得出结论二维数组中的每个元素都是连续存放的
如图所示:
在这里插入图片描述


3、sizeof计算数组元素个数

sizeof是C语言中的一个关键字,是可以计算类型或者变量大小的,它也可以计算数组的大小。
例如:

int arr[10]={0};
printf("%d\n",sizeof(arr));//结果为40字节

理解:arr数组中存放有10个元素,每个元素都为int类型,而我们知道int类型大小为4个字节,因此数组arr的大小为4*10=40,注意单位是字节
此外,我们又知道数组中的所有元素的类型都是相同的,那么只要计算出一个元素所占的字节个数,就可以算出数组的元素个数了。

int arr[10]={0];
int sz = sizeof(arr)/sizeof(arr[0]);
printf("%d\n",sz);//结果为10

理解:用数组的总大小除以每个数组元素的大小,就可以算出数组中的元素个数了,一般习惯直接用arr[0]来算,当然也可以用其他的元素,结果都是一样的。

总结:

  1. sizeof()操作符用于取长度,以字节为单位。sizeof(数组名)即求的是整个数组的大小。sizeof(首元素)即求数组单个元素的大小,用0下标,是因为数组至少存在一个有效元素,所以0下标永远存在。
  2. 数组的大小可以用sizeof()计算得到。计算方式为sizeof(arr)/sizeof(arr[0])

4、冷门小知识——C99中的变长数组

在C99标准之前,C语言在创建数组的时候,数组大小的指定只能使用常量、常量表达式,或者是在初始化时省略数组大小。
例如:

int arr1[10];
int arr2[3+5];
int arr3[]={1,2,3};

由以上的例子我们发现,这样的语法限制,让我们创建的数组不够灵活,有时数组过大就浪费了空间,有时数组又太小不够用。

所以C99标准中给了一个变长数组的新特性,允许我们可以使用变量指定数组的大小。
例如:

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

数组arr就是变长数组,因为它的长度取决于变量n的值,编译器没法事先确定,只要运行时才知道n是多少。

变长数组的根本特性,就是数组长度只有运行时才能确定,所以变长数组不能初始化。它的好处是程序员不必在开发时,随意为数组指定一个估计的长度,程序可以在运行时为数组分配精确的长度。但要注意一个容易迷惑的点,就是变长数组的意思是数组的大小是可以使用变量来指定,在程序运行的时候,根据变量的大小来指定数组的元素个数,而不是说数组的大小是可变的。数组的大小一旦确定就不能再改变了

总结——数组的特点:

  • 数组是一组相同类型元素的集合。
  • 数组中存放的是1个或者多个数据,但是数组元素个数不能为0。
  • 数组中存放的多个数据,类型是相同的。
  • 数组分为一维数组和多维数组,多维数组一般比较多见的是二维数组。

在这里插入图片描述

  • 36
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 38
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 38
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小覃同學

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值