Bootstrap

C语言二维数组与指针

这里真的很想好好讲讲,我发现有些教材、网课甚至线下课在这里基本没有细细讲解用法,而是就是用一堆sizeof打印二维数组的大小,看内存栈,但是没有教具体实际怎么去用(个人感觉字符串那里也是,教的都是一些内存上的东西,没有讲解具体用法)。

其实这一块最重要的就是语法,要不轻轻松松爆内存。

什么是二维数组

就是一个数组,但是有两个维度,可以按照矩阵理解,一个管列一个管行

int a[3][4]        定义了一个数字矩阵,有3行4列

char a[3][4]     定义了一个字符矩阵,有3行4列(注意不是字符串,每个元素只能是一个字母,字符串开个坑先)

指针与数组

有两个东西,怎么区分?看用途

数组的指针

指向用,比如我有一个矩阵,我不想破坏他,想用一个数组的指针指向他然后进行打印操作或者其他操作,取值或者赋值但是不直接更改原先二维数组,这时候就是数组的指针

int (*p)[4]    //用来指向一个包含四个元素的数组

举个例子

#include <stdio.h>
int main()
{
    int a[3][4], i, j;
    int(*p)[4];        // 定义p为指针,指向一个长度为4的整型数组
    p = a;
    
    /********** Begin *********/
    // 使用指向数组的指针输入二维数组的值
    for(i = 0; i < 3; i++) {
        for(j = 0; j < 4; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &p[i][j]);
        }
    }
    
    // 使用指向数组的指针输出二维数组的值
    for(i = 0; i < 3; i++) {
        for(j = 0; j < 4; j++) {
            printf("%d ", p[i][j]);
        }
        printf("\n");
    }
    /********** End **********/
    
    return 0;
}

这里我不想直接修改a(虽然也行,但是有个指向数组的指针这样可以方便动态分配、指针运算、函数参数传递、避免类型不匹配),就弄了个p指针,专门指向有四个元素的数组(这样就安全了),这个int (*p)[4]相当于把矩阵切成三行,指针运算p=p+1就可以跳过一个行,比没有p指针跳过行方便多了

指针数组

一个数组,里面存放的全是指针,所以用途是存放指针,比如有四个字符串(四个指针),我想把他们再汇总,就用指针数组,这个数组里面存放四个指针,分别指向四个句子

int *p[4]    //可以存放四个指针

 举个例子,还是矩阵

#include <stdio.h>

int main() {
    // 定义三个数组
    int array1[4] = {1, 2, 3, 4};
    int array2[4] = {5, 6, 7, 8};
    int array3[4] = {9, 10, 11, 12};
    

    // 定义一个指针数组,每个元素都是一个指向 int 的指针
    int *ptrArray[3];

    // 将指针数组的每个元素指向对应的数组
    ptrArray[0] = array1;
    ptrArray[1] = array2;
    ptrArray[2] = array3;
    

    // 使用指针数组遍历并打印每个数组的内容
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 4; j++) {
            printf("%d ", ptrArray[i][j]); // 使用 ptrArray[i][j] 访问元素
        }
        printf("\n");
    }

    return 0;
}

这里相当于 先定义了每个行向量,然后再拼在一起(指针数组主要起汇总作用)

怎么创建

个人建议:

数字、字母二维矩阵 用 数组的指针指着创建(实在懒直接对创建的二维矩阵操作也不是不行)

字符串(一段话) 用 指针数组

这里就讲解用数组的指针创建的方法,字符串的回头再说

首先要定义一个二维数组(开辟个空间,所以指针写法就不行了)

int a[3][4], i, j;

然后就是弄个数组指针指向a

int(*p)[4];        // 定义p为指针,指向一个长度为4的整型数组
    p = a;

对于数、字符,输入输出都好说,双循环就行,一般外层循环管行,内层循环管列

因为p指向a,所以这种写法也可以,看着也方便 

这个就是指针运算的写法,在这个问题上有些复杂*(p+i)表示行的移动,+j表示列的移动 

怎么遍历

也是双层循环,两种写法

总结

二维数组这里牵扯指针知识,有些写法等价,有些却不等价,需要琢磨一段时间,主要还是思考这东西我定义的到底是什么,后面也会作为重点着重讲解,这一块一定要大量的习题

然后这是上面两个东西的区分图

以上均是本人理解,如有不对欢迎各位大佬评论区指出~

;