1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 【C语言】数组(一维数组 二维数组)

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

时间:2021-07-23 06:11:59

相关推荐

【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,6int 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,6int 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);//1printf(" arr[0] = %p\n", arr);//2printf(" &arr[0] = %p\n", &arr[0]);//3printf("&arr + 1 = %p\n", &arr + 1);//4printf(" arr + 1 = %p\n", arr + 1);//5return 0;}

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。