数组的个人理解

数组的个人理解:

文章内容主要是对一维数组和二维数组的介绍

一维数组:

1. 一维数组的创建和初始化:
一维数组的创建方式:
type_t   arr_name   [const_n];
//type_t ࣳ是指数组的元素类型 
//const_n 是一个常量表达式,表示数组的大小。
//例子1
int arr[10];
//由于数组是由0,所以数组创建后可使用的最大单元为const_n-1,即0~const_n-1。
//上面创建的数组的长度为10,可以使用的单元为arr[0]~arr[9]。
//例子2
int tmp = 10;
int arr[tmp]; 
//这里创建会出现问题,因为tmp是一个变量,而[ ]中需要的是一个常量表达式,因此,创建会失败。

一维数组的初始化方式:

//一维数组的初始化
    int arr0[5];
    int arr1[10] = { 0 };
    int arr2[5] = {};
    int arr3[5] = { 1,2,3,4,5 };
    int arr4[5] = { 1,2 };
    char arr5[] = "abcde";
    char arr6[5] = { 'a','b','c' };
    char arr7[5] = { 0 };
    char arr8[5] = { 32,48,59 };
    //这些数组初始化后,数组中存储的值是什么呢?我们看下面的图片:

数组初始化
通过上面的图片我们可以看到,如果在定义数组时对数组不进行初始化,那么它的值就会是随机值。
如果对数组进行初始化,{}中出现的值,会依次从数组的首个元素开始初始化,如果有的数组成员未在{}中出现,那么它就会将其初始化为0。字符数字则默认初始化为‘\0’。
在创建数组时,如果不想直接指定数组的大小,则可以根据初始化的内容来确定。在初始化时,有两种方法。

    char arr5[] = "abcde";
    char arr10[] = { 'a', 'b', 'c' };

未定义数组的初始化
在进行以上两种方法的初始化时,需要注意数组的长度。

2. 一维数组的使用:

一维数组的使用,说白了就是对数组中各个成员的访问,对数组成员的访问,我们可以通过下标的方式,在访问时,只需要借助[ ]操作符就可以做到。
而在有时,我们需要使用指针的方式来访问数组,这个时候我们需要搞明白的问题就是,成员的存储方式是什么样的。

    int arr3[5] = { 1,2,3,4,5 };
    for (i = 0; i < 5; i++)
    {
        printf("&arr3[%d] = %p\n", i,&arr3[i]);
    }
    //定义一个数组,并对数组每个元素的地址进行输出

数组元素地址输出
通过输出地址我们可以看出,数组的元素在存储时,是连续存储的。而我们都知道,数组名是数组首元素的地址,因此,我们只需要给这个地址加上一定的偏移值,就可以做到分别访问数组的各个成员。我们可以模拟出它在内存中的存储布局:
这里写图片描述

//举个例子
    int arr3[5] = { 1,2,3,4,5 };
    for (i = 0; i < 5; i++)
    {
        printf("arr3[%d] = %d   ", i, arr3[i]);
        printf("*(arr3 + %d) = %d", i, *(arr3 + i));
        printf("\n");
    }
// * 是解引用操作符,得到指针所指向的地址的内容。

数组访问

通过输出的结果,可见,两种方式访问数组,得到的结果是一样的。
对于一维数组的操作还有一点需要我们注意

    int arr3[5] = { 1,2,3,4,5 };
    printf("arr3 = %p \n", arr3);
    printf("&arr3 = %p \n", &arr3);
    printf("(&arr3) + 1 = %p \n", (&arr3) + 1);

数组取地址加一
我们可以看到,当对数组名直接加一时,指针的偏移量是一个数组成员的字节大小,当对数组名取地址进行加一时,指针偏移量为整个数组的大小,也就是20个字节,所以,当对数组名取地址时,得到的地址虽然和数组名的地址相同,但是表示的意思却是完全不同的。

  • 数组名表示的是数组首元素的地址,所以进行加一运算后,指针偏移了一个成员的字节大小。
  • 数组名取地址表示的是数组的地址,所以进行加一运算后,指针偏移了整个数组的大小。

二维数组

二维数组的创建和初始化
//二维数组的创建
int arr[3][4];
char arr0[3][3];
//二维数组的初始化
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};
char arr[3][4] = {'a','b','c','d'};

二维数组的创建方式与一维数组相似,因此在这不做过多赘述,值得注意的是,虽然二维数组也可以在定义时不指定数组的大小,等数组初始化时通过参数再来指定,但对于行的大小却是必须在定义时指定清楚的。
对于二维数组的访问,同样也有两种,通过下标和通过指针,所以我们同样应该搞清楚二维数组在内存中的存储方式。

//创建一个二维数组,输出每个元素的地址
    int arr[3][2] = { {1, 2}, {3, 4}, {5, 6} };
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 2; j++)
        {
            printf("&a[%d][%d] = %p   ", i, j, &arr[i][j]);
        }
        printf("\n");
    }

二维数组元素地址输出

通过这段代码我们可以发现,二维数组在内存中,也是连续存储的,因此我们可以和访问一维数组那样,通过指针来访问。我们可以模拟画出它在内存中的存储布局。
内存模拟图

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

数组输出
通过运行这段代码,我们可以看到数组名arr ,数组名取地址&arr, 首元素arr[0][0]地址, 以及第一行地址arr[0]的值都是一样的。但是当他们加一以后,地址的偏移量却是不同的,所以我们可以根据他们地址的偏移量来得出他们所表示的含义。

  • arr ——数组名,arr+1,地址增加了8 。
    printf("arr + 1         = %p\n", arr + 1);
    printf("arr[1]         = %p\n", arr[1]);

观察上面输出的截图,我们可以看到当arr + 1 后,它的地址变成了arr[1]的地址,也就是二维数组第二行整体的首地址地址,一次跳过了第一行的两个元素。因此我们可以把二维数组想象为一个新的一维数组,这个新的一维数组的每个元素就是二维数组的每一行,所以arr 表示的时 它的值的含义为 二维数组第一行的首地址,对它进行加减操作,地址的变化是以行为单位的。对它作以图解:
二维数组转换

  • &arr ——数组名取地址,&arr+1,地址增加了24 ,也就是偏移了整个二维数组的大小。因此,它代表的时二维数组的地址,它的加减单位是整个二维数组。

  • arr[0] ——二维数组第一行的首地址,arr[0] + 1,地址增加了4 ,也就是偏移了第一行一个元素的字节大小的地址。因此,它代表的是把二位数组想象成一个新的一维数组,它就是这个新一维数组的首元素,对它加一,就是进到它内部来,求它包含的元素的地址。它的加减单位是每行的单个元素的大小。

  • &arr[0][0] ——二维数组首元素的地址,&arr[0][0] +1, 地址增加了4,也是一个元素的字节大小的地址。因此它代表的是二维数组中元素的地址,它的加减单位是元素的字节大小。

  • 后面几个是根据这些情况对二维数组中的元素进行输出。

以上就是我对于数组的个人理解,不足之处还望指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值