C语言——数组知识点总结(超详解)

本文详细介绍了C语言中一维数组的创建、初始化方法,以及如何通过下标操作访问元素。同时扩展至二维数组,讨论了其创建、初始化、使用和内存存储特性,并强调了数组作为函数参数时的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一. 一维数组

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

                (1)数组的创建

                (2)数组初始化

完全初始化

不完全初始化

字符数组存放字符串

        1.2. 一维数组的使用

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

二. 二维数组

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

                (1)二维数组的创建

                (2)二维数组初始化

        2.2. 二维数组的使用

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

三. 数组作为函数参数

3.1.数组名是什么?

3.2.作为函数参数


一. 一维数组

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

                (1)数组的创建

在创建数组之前,我们应先了解数组是什么?

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

数组的创建方式:

type_t   arr_name [const_n];

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

创建数组成功的实例:

// int 类型
int arr1[10];
int arr2[5];

// char 类型
char arr3[5];
char arr4[3];

// float/double 类型
float arr5[2];
double arr6[4];

创建数组错误的实例: 

int n = 10;
int arr[n];    // 此时的 n 是个变量

注意:数组的创建,[ ] 中要给一个常量才可以,不能使用变量。

                (2)数组初始化

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

注:数组在创建的时候如果不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定。

int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 1,2 };
char arr3[] = { 'a','s','b','d' };

此时编译器就会默认 arr1数组的大小是5, arr2数组的大小是2, arr3数组的大小是4。

完全初始化

数组内最多能存放几个元素就初始化几个元素。

int arr1[3] = { 1,2,3 };
int arr2[5] = { 1,2,3,4,5 };
char arr3[3] = { 'a','b','c' };
double arr4[5] = { 12.1,13.4,1.3,6.8,5.9 };
不完全初始化

初始化的元素小于数组内定义的元素大小,并且剩余的元素默认为 0。

字符数组存放字符串
char arr[] = "abcdef";

初始化后元素在数组中的位置: 

' \0 ' 只是字符串的结束标志,是一个转义字符,并且在计算字符串长度时不作为字符串中内容,即此 arr 数组的大小长度为 6。 

:若省略数组大小,则数组就必须得初始化,数组的大小是根据初始化的内容来决定的。

        1.2. 一维数组的使用

[ ]:下标引用操作符,其实就是数组访问的操作符。

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

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

为什么 sz 就是数组的大小呢?不要急,后面的数组作为函数参数一节有着详细的讲解。 

实战一下:

#include<stdio.h>
int main()
{
	int arr[5] = { 0 };	  // 数组的不完全初始化 
	int sz = sizeof(arr) / sizeof(arr[0]);	// 用来计算数组的元素个数
	
	// 数组是使用下标来访问元素的,下标从0开始
	int i = 0;	// 做下标,用于访问数组的各个元素
	for (i = 0; i < sz; i++)
	{
        // 给数组赋值
		arr[i] = i;
	}
	// 打印数组内容
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

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

要了解数组在内存中的存储,就要了解 %p (打印数据的地址)。

#include<stdio.h>

int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("&arr[%d] = %p\n", i, &arr[i]);
	}
	return 0;
}

输出结果:

观察:地址以 4 个字节(int 类型的数组)的相差依次增大。

通过输出的结果,我们了解到:随着数组下标的增长,元素的地址也以 有规律的增长,故此,数组在内存中是连续存放的。

二. 二维数组

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

                (1)二维数组的创建

一维数组的性质二维数组基本上都有,二维数组的创建:

type_t   arr_name [const_n1][const_n2];

type_t   数据类型	
const_n1  二维数组行号,决定含有几行
const_n2  二维数组列号,决定含有几列

// 二维数组的创建
	int arr[2][3];    // 此数组有 2行3列
	char arr1[3][4];  // 此数组有 3行4列
	float arr2[4][5];

在创建二维数组时,二维数组的行号可以省略,但列号一定不能省略。

// 正确示范
int arr[3][4];
char arr2[][3];

// 错误示范
int arr3[2][];
char arr4[][];

                (2)二维数组初始化

    // 数组的初始化
	int arr[3][4] = { 1,2,3,4 };
	int arr1[3][4] = { {1,2},{3,4} };
	int arr2[][4] = { {2,3},{5,6} };

这时,arr1 和 arr2 中的一个{}标志着一个一维数组 ,即二维数组相当于多个一维数组相连接起来,第一个{}(一维数组)为此二维数组的第0行,第二个{}(一维数组)为此二维数组的第1行等。

        2.2. 二维数组的使用

二维数组的使用也是通过下标的方法(通过双重循环嵌套法):

#include<stdio.h>

int main()
{
	int arr[3][4] = { 0 };
	int i = 0;
	int j = 0;
	// 给二位数组赋值
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			arr[i][j] = i + j;
		}
	}
	// 打印二维数组
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

分析:此时的 i 决定二维数组在第几行,j 决定在第几列。

先赋值第一行,在赋值第一行这个“一维数组”。

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

同样的,我们要了解二维数组在内存中的存储,就要先观察二维数组各个元素的地址

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

代码结果:

分析:我们可以看到二维数组也是在内存中连续存储的。

由分析我们还可以得出:二维数组其实可以看作是一维数组的数组。

三. 数组作为函数参数

3.1.数组名是什么?

在理解函数参数之前,我们必须得了解函数名到底是什么。
看代码:
#include<stdio.h>

int main()
{
	int arr[5] = { 1,2,3,4 };
	printf("%p\n", arr);
	printf("%p\n", arr + 1);
	printf("%p\n", &arr[0]);
	printf("%p\n", &arr[0] + 1);
	printf("%d\n", *arr);
	return 0;
}
打印结果:
结果:数组名就是数组首元素的地址(有两个例外)。
两个例外:
        1. sizeof(数组名)(sizeof(arr)) ,计算整个数组的大小,sizeof内部单独存放一个数组名,此时数组名表示整个数组。
        2. &数组名(&arr),取出的是数组的地址,&数组名表示整个数组。
除了这两种情况,其他的所有情况数组名都表示数组首元素的地址。
啥也不说,咱看代码:
#include<stdio.h>

int main()
{
	int arr[5] = { 1,2,3,4 };
	printf("%p\n", arr);
	printf("%p\n", arr + 1);
	printf("%p\n", &arr[0]);
	printf("%p\n", &arr[0] + 1);
	printf("%p\n", &arr);
	printf("%p\n", &arr+1);
	printf("%zd\n", sizeof(arr));
	printf("%zd\n", sizeof(arr[0]));
	return 0;
}

运行结果:

由结果不难看出:sizeof(arr) 和 &arr 都表示了整个数组,故此:则就能用 sizeof(arr)/sizeof(arr[0]) 来求出数组元素的个数。

3.2.作为函数参数

在写代码的时候,往往不可避免的会将数组作为参数传给这个函数。比如:要实现一个专门打印数组的函数。

#include<stdio.h>

void Print(int arr[])
{
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[] = { 1,2,3,4,5,6 };
	Print(arr);
	return 0;
}

大家看一下:这样的代码行吗?

发现:打印结果是:1 2

why?

这是因为当数组传参的时候,实际上只是把数组的首元素的地址传递过去了,所以即使在函数参数部分写成数组的形式,int arr[]表示的依然是一个指针,int* arr,以前的文章已经说明 sizeof(指针)结果是4/8,(因为我的编译器是64位的,所以我的 sizeof(arr) 是 8,此时sz = 2,故打印 2位就不再打印了)

那该如何写呢

上述代码的主要错误就是因为 sz 的值错了,那么在传参的时候将 sz 的值传过去,行吗?

看代码:

#include<stdio.h>

void Print(int arr[],int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[] = { 1,2,3,4,5,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	Print(arr,sz);
	return 0;
}

发现是可以的。OK了

所以老铁们以后再对数组传参的时候要把数组的大小要传过去。

今天的分享就到这里了,若有大佬观察到这篇博文中的问题恳请大佬们不吝赐教。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值