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

一. 一维数组

        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。 

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

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

        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 类型的数组)的相差依次增大。

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

二. 二维数组

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

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

#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 决定在第几列。

 

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

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

代码结果:

 

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

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

 

三. 数组作为函数参数

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]) 来求出数组元素的个数。

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了

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

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

  • 21
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值