C语言第八课:数组(上)——数组的创建、初始化、使用与存储

目录

前言:

一、数组:

1.定义:

2.数组的创建方式:

3.创建注意:

二、一维数组:

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

2.一维数组的使用:

3.一维数组在内存中的存储:

三、二维数组:

1.二维数组的创建与初始化:

2.二维数组的使用:

3.二维数组的存储:


前言:

        之前我和各位小伙伴们分两个模块学习了函数的相关知识,通过文末的练习相信各位小伙伴们对函数的相关内容也有了自己的认识与理解。而本文我们将进入到数组的相关知识的学习中,希望各位小伙伴们再接再厉,牢固掌握文中提到的所有知识点。

一、数组:

1.定义:

        数组是一组相同类型元素的集合

2.数组的创建方式:

        数组的创建由三部分组成:元素类型数组名数组大小

type_t arr_name[const_n];
//type_t 是指数组的元素类型
// arr_name 是指数组的名称,由创建者自定义
//const_n 是常量或常量表达式,用于指定数组的大小

3.创建注意:

        数组的创建,在C99标准之前,[const_n]中必须给一个常量(或常量表达式)才可以,不可以使用变量,会报错。而在C99标准之后,该标准支持了变长数组的概念,数组的大小可以使用变量指定,但是数组不能初始化

        数组在创建时若不想指定数组的确定大小就必须进行初始化,数组的元素个数将根据初始化时的内容来确定。

        但应当注意对下述代码的区分:

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

        这两组代码的区别是什么呢?我们来看:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

int main()
{
	char arr1[] = "abc";
	char arr2[] = { 'a','b','c' };

	//查看数组大小:
	printf("arr1大小:%d\n", sizeof(arr1));
	printf("arr2大小:%d\n", sizeof(arr2));

	//查看数组内容:
	printf("arr1中内容:%s\n", arr1);
	printf("arr2中内容:%s\n", arr2);

	return 0;
}

         将其运行起来我们来看结果:

        为什么两种初始化方式小小的区别会有如此之大的差距呢? arr2中的内容又为何会多出后方那些莫名其妙的东西呢?

        这是因为在使用“ "..." ”进行初始化时,会自动为我们的数组abc内容后添加一个结束标志"\0",于是在我们使用sizeof查看数组arr1的数组大小时,显示出来的实际为"abc\0",故显示为4;而当我们使用“ {...} ”时却不会,数组中的元素数为3。

        而当我们查看数组中内容时,在我们之前的学习中我们提到过,printf函数在屏幕上进行打印时,直到读取到第一个结束标志"\0"时才停止。在使用“ "abc" ”时由于其自动加上了结束标志"\0",故打印"abc"后停止,而“ {...} ”由于没有结束标志,导致printf函数在打印时不断读取随机数直至读取至结束标志"\0"才停止,而在这期间读取到的所有随机值都会进行打印。

二、一维数组:

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

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

int arr1[5] = { 1,2,3,4,5 };
//int表示数组内元素的类型为整形,数组名为arr1,常数5表示数组内最多存放五个数据元素,大括号括起来使用逗号分隔开的数据即为数组元素
//完全初始化:在对数组进行初始化时,给数组的初始值数量,等于数组大小的初始化
	
int arr2[5] = { 1,2,3 };
//不完全初始化:在对数组进行初始化时,给数组的初始值数量,小于数组大小的初始化

int arr3[] = { 1,2,3,4,5 };
//不指定大小的初始化:在对数组进行初始化时,若未指定数组大小,将根据数据元素数自动确认

char arr4[5] = { 'a','b','c','d','e' };
//字符型数组的初始化:在对字符型数组进行初始化时,初始值需用英文单引号" '' "引住
//字符型数组的完全初始化

char arr5[5] = "abcde";
//字符型数组的另一种初始化形式

char arr6[5] = { 'a','b','c' };
//字符型数组的不完全初始化

        特别注意,在初始化字符型数组时,若使用“ {...} ”进行初始化,其中数字字符元素必须使用单引号“ '...' ”引住才可以。若不使用单引号,将会存放以该数字为ASCII码值的对应字符

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

int main()
{
	char arr[] = { 'a',98,'c','\0' };
	//小写字母b对应的ASCII码值为98
	printf("数组arr的内容为:%s\n", arr);

	return 0;
}

        运行结果:

2.一维数组的使用:

        对于数组的使用,有这样一个符号:[...],即下标引用操作符。它也是数组访问的操作符

        数组中元素的表示是依靠下标引用操作符来实现的,且数组中,元素的下标是从零开始的。例如数组arr[10]中的数组元素下标为0~9,其中arr[0]表示第一个元素arr[1]表示第二个元素…以此类推。

        而数组的使用各位小伙伴们们可以看下述代码:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

int main()
{
	int arr[10] = { 0 };
	//不完全初始化

	int sz = sizeof(arr) / sizeof(arr[0]);
	//计算数组内元素个数
	//数组arr总长度 除以 单元素数组长度

	int i = 0;
	//定义元素下标
	for (i = 0; i < 10; i++)
	//创建数组时最大值为10,下标应为0-9,故应当在i<10时进行赋值
	{
		arr[i] = i + 1;
		//数组下标从零开始故第i+1个元素arr[i]应赋值为i+1
	}

	for (i = 0; i < 10; i++)
	{
		printf("arr[%d] = %d\n", i, arr[i]);
	}

	return 0;
}

        编译运行,结果正确,达到期望目的: 

3.一维数组在内存中的存储:

        那么一维数组在内存中是如何存储的呢?我们简单的写出代码来看一看各个数据元素的存储地址

#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++)
	//sz为数组实际元素个数,写成这种形式可以防止数组越界,是更好的代码风格
	{
		printf("arr[%d]的存储地址为:%p\n", i, &arr[i]);
	}

	return 0;
}

        编译运行后,我们来观察它们的地址:

        通过我们的仔细观察,我们发现,随着数组下标的增长,元素的地址也在有规律的递增。

        由此我们可以得出结论:数组在内存中是连续存放的。(由低地址向高地址存放) 

三、二维数组:

1.二维数组的创建与初始化:

        二维数组的创建与一维数组类似,其二维表现在其下标具有 行 和 列 两个下标,行在前,列在后,且与与一维数组相同均从零开始:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

int main()
{
	int arr1[3][4];
	//创建三行四列的整型数组

	char arr2[5][6];
	//创建五行六列的字符型数组

	double arr3[7][8];
	//创建七行八列的浮点型数组

	return 0;
}

        二维数组中的初始化与一维数组同样类似

        不过不同的是,每一行可以不存满,数组将会自动按照每行存满后存入下一行的方式进行存储;若某行没有存满,且想要开始存入下一行时,应当使用一组“ {...} ”划来分行:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

int main()
{
	int arr1[2][2] = { 1,2,3,4 };
	//完全初始化:存入方式为第一行存入1、2,第二行存入3、4

	int arr2[3][4] = { 1,2,3,4 };
	//不完全初始化:存入方式为第一行存入1、2、3,第二行存入4

	int arr3[3][4] = { {1,2},{3,4} };
	//不完全初始化:存入方式为第一行存入1、2,第二行存入3、4

	return 0;
}

        同时特别注意,二维数组在初始化时,行可以省略,列不可以省略

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

int main()
{
	int arr1[][2] = { 1,2,3,4 };
	//等同于↓
	int arr2[][2] = { {1,2},{3,4} };

	return 0;
}

        原理其实也很简单,各位小伙伴们来想一想,如果我们仅仅规定了行,却没有规定列,在存储一段数据时,如何知道何时该换行呢?

        反之,只要我们规定了列,就算没有规定行每一行只要存满数据,进行自动换行即可,仍然可以完成二维数组的存储。

2.二维数组的使用:

        二维数组与一维数组的使用同样类似,均通过下标进行操作:

#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;
			//存入对应数据
		}
	}

	int k = 0;
	for (k = 0; k < 3; k++)
	{
		int l = 0;
		for (l = 0; l < 4; l++)
		{
			printf("arr[%d][%d] = %-2d ", k, l, arr[k][l]);
		}
		printf("\n");
	}

	return 0;
}

        同样进行编译运行,可以看到结果正确,达到了我们的期望目的:

3.二维数组的存储:

        二维数组的存储会和一维数组相同吗?我们还是写出代码来验证一下:

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

        编译运行,观察其地址;

        一目了然,与一维数组的存储相同,二维数组在内存中的存储也是连续的。(由低地址到高地址存放) 

        到这里我们今天的学习就告一段落啦,各位小伙伴们认真学习仔细消化,我们下次再见叭!志坚者,功名之柱也。登山不以艰险而止,则必臻乎峻岭。

        新人初来乍到,辛苦各位小伙伴们动动小手,三连走一走 ~ ~ ~  最后,本文仍有许多不足之处,欢迎各位看官老爷随时私信批评指正!

  • 22
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
### 回答1: 我不太清楚定义不定长数组的具体方法,但是可以提供一些示例:在C语言中,可以使用指针数组定义不定长的数组,其中指针数组的每个元素都是一个指针,这些指针指向不同长度的数组。另外,还可以使用变长数组定义不定长的数组,变长数组的长度可以在运行时动态改变。 ### 回答2: 在C语言中,可以使用指针和动态内存分配来定义一个不定长(可变长度)的数组。具体步骤如下: 1. 首先,定义一个指针变量,用于存储数组的首地址。例如:int* arr = NULL; 2. 然后,通过动态内存分配函数malloc()来为数组分配所需的内存空间。例如:arr = (int*)malloc(size * sizeof(int)); 这里的size是根据需要定义的数组长度,可以通过用户输入或其他逻辑来获取。 3. 分配完内存后,就可以使用arr指针来访问该数组了,而且该数组的长度是可变的。 例如,可以通过arr[index]来访问第index个元素,其中index的范围是从0到size-1。 4. 最后,在程序结束时,需要释放动态分配的内存空间,以防止内存泄漏。使用free()函数来释放内存,例如:free(arr); 综上所述,通过指针和动态内存分配,我们可以定义一个不定长的数组,在程序运行过程中根据需要动态分配和释放内存,实现数组长度的动态变化。 ### 回答3: 在C语言中,要定义一个不定长的数组,可以使用动态内存分配来实现。 动态内存分配是通过C语言提供的malloc函数来实现的。它可以在运行时根据需要动态地分配内存。配合使用sizeof操作符来确定所需的内存大小,可以创建一个不定长的数组。 具体步骤如下: 1. 首先,我们需要声明一个指针变量来表示数组,例如: ```c int *array; ``` 2. 然后,使用malloc函数来为数组分配所需的内存空间: ```c array = (int*)malloc(n * sizeof(int)); ``` 这里的n表示数组的长度,所需的内存大小为n个int类型的变量。 3. 现在,我们可以使用数组进行操作,例如给数组元素赋值: ```c array[0] = 10; array[1] = 20; ``` 注意,在使用数组后,需要使用free函数释放分配的内存,以避免内存泄漏: ```c free(array); ``` 通过以上步骤,我们成功定义了一个不定长的数组。这种动态内存分配的方法可以在程序运行时根据需要创建数组,使得程序更加灵活和高效。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

銮崽的干货分享基地

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

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

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

打赏作者

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

抵扣说明:

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

余额充值