【C语言】数组(一维数组、二维数组)

目录

一、一维数组

        1、一维数组的创建(定义)

        2、一维数组的初始化

         3、一维数组的内存分配       

二、二维数组

        1、二维数组的创建(定义)

        2、二维数组的初始化

        3、二维数组的内存分配

三、数组越界

四、详解数组名


一、一维数组

        1、一维数组的创建(定义)

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

            数组的创建(定义):

                                      <数据类型>       <数组名><[常量表达式]>;

            数据类型:是指数组的元素类型(对于同一个数组,其所有元素的数据类型都是相同的)

            常量表达式:用来指定数组的大小(元素个数×类型大小)

            数组名:自定义的数组名字,可以由字母、数字和下划线组成,但要注意不能以数字开头

        2、一维数组的初始化

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

                数组的初始化有7种情况:

                ①局部数组不初始化

                        对于普通局部数组,若定义时没有初始化,则数组中元素的值是随机的。

        

#include <stdio.h>

int main()
{
    int arr[1];//为了方便演示,创建了一个只有1个元素的数组
    printf("%d\n",arr[0]);//打印这一个元素的值
    return 0;
}

    

                ②static数组不初始化

                        对于static修饰的数组,若定义时没有初始化,则数组中元素的值默认为0。

#include <stdio.h>
int main()
{
    static int arr[1];//static修饰的数组
    printf("%d\n", arr[0]);
    return 0;
}

                        输出结果为0。

                ③全局数组不初始化

                        对于全局数组,若定义时没有初始化,则数组中元素的值默认也为0(偷懒就不举例验证了qaq)。

                ④全部初始化

                        与变量在定义时初始化一样,数组也可以在定义时进行初始化,如对整形数组进行初始化。

                需要注意:定义数组时,对数组元素的初始化,只能写成一行,不能换行写,下面是错误示范: 

                 ⑤部分初始化

                        数组在定义时可以对其中的部分数据进行初始化,当{}中值的个数少于元素个数时,只给前面部分元素赋值,后面未赋值元素自动赋0。

                ⑥数组全部赋值 

                        若对数组全部赋值,则可以省略数组下标中的常量。

                ⑦数组全部初始化为0

        以上就是数组初始化的7种情况,需要注意的是:数组的元素是不能整体赋值的,只能单个赋值,如int arr[3] = {4};则只为该数组真的第一个元素(arr[0])赋值。

         3、一维数组的内存分配       

         在内存中,数组中的元素占用连续的存储空间,并且根据单个元素所占存储空间来进行内存分配。数组名代表数组的起始地址,是地址常量,对数组名求sizeof,可以得出数组占用的总空间。从此我们可以利用数组总空间求出元素个数。

数组元素个数 = sizeof(数组名)/ sizeof(数据类型)

          接下来我们通过一段代码来应用一下,在进一步看看每个元素的地址:

include <stdio.h>

int main()
{
	int arr[5] = { 0 };
	int i;
	int sz = sizeof(arr) / sizeof(arr[0]);//求出元素个数
	for (i = 0; i < sz; i++)
	{
		printf("arr[%d] = %p\n", i,&arr[i]);//打印出每个元素的地址
	}
	return 0;
}

         仔细观察输出的结果,我们发现,随着数组下标的增长,元素的地址也是有规律(数据类型大小的增长)的递增。

二、二维数组

        1、二维数组的创建(定义)

                一维数组只有一个下标。具有两个下标的数组,就称为二维数组。二维数组元素有两个下标,以标识它在数组中的位置。二维数组的说明与一维数组的说明基本类似,其形式如下:

                <数据类型>     <数组名><[常量表达式1]><[常量表达式2]>;

                eg:int arr[3][4];说明这是一个2行3例的数组。(同一维数组一样从下标[0]开始的)

                可以看出,二维数组只是比一维数组多了一个下标,其他特性与一维数组相同。

        2、二维数组的初始化

                二维数组的初始化与一维数组基本类似,主要有以下形式:

                ①降维给二维数组赋初值,即按行初始化。每一组的初始化都用{}括起来。

                        

int arr[2][3] = {{1,2,3},{4,5,6}};
//按降维给arr数组全部初始化,第一行为1,2,3。第二行为4,5,6
int arr1[2][3] = {{1},{4}};
//部分初始化,其他元素为0。第一行为1,0,0。第二行为4,0,0

                ②按线性存储的形式给二维数组赋初值

int arr[2][3] = {1,2,3,4,5,6};
//按线性存储方式给arr数组全部初始化,第一行为1,2,3。第二行为4,5,6
int arr1[2][3] = {1,4};
//部分初始化,其他元素为0。第一行为1,4,0。第二行为0,0,0

                ③可以省略下标的方式,给二维数组赋初值

int arr[][3] = {1,2,3,4,5,6};
//省略第一维的长度,给数组赋值(上面2种方法都可以)

        这里需要注意,第一维长度可以省略,第二维长度坚决不能省略。如int arr[3][ ];int arr[ ] [ ];这两种都是错的。

        3、二维数组的内存分配

        二维数组在概念上是二维的,也就是称其两个下标为行和列。但是内存确是按照一维线性排列的,二维数组如何在内存中存储,我们通过以下代码了解:

#include <stdio.h>

int main()
{
	int arr[3][4] = {0};
	int i, j;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("arr[%d][%d] = %p\n", i,j,&arr[i][j]);
		}
	}
	return 0;
}

         通过结果我们可以看出,其实二维数组同一维数组一样,在内存中也是连续存储的。

三、数组越界

        数组的下标是有范围限制的,数组的下标规定是从0开始的,通过我们之前的代码可以看出,如果数组有n个元素,那么在最后一个元素的下标就是n-1。

        如果我们在写代码时数组的下标小于0或者大于n-1,那么就是数组越界访问了,超出了数组合法空间的访问。

                eg:  int  arr[5] = {1,2,3,4,5,6};

        二维数组的行和列同样存在越界。

四、详解数组名

        

       由上图可以看出,数组名就是数组首元素的地址。但是有两个例外。

        1、sizeof(arr),这里的数组名arr表示整个数组,sizeof(arr)是在计算整个数组的大小(字节)。

        2、&arr,数组名表示的是整个数组,求出来的是整个数组的地址。我们通过代码来验证一下这个说法:

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

         代码1,2,3输出结果是一样的,但是第一个&arr取出的是整个数组的地址,和2,3的意义完全不一样的,2,3是首元素的地址。我们通过4,5输出结果可以验证我们的结论,4输出的结果比1输出结果多了12字节(这个数组的大小),5输出的结果比2多了4字节(一个元素的大小)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值