leetbook学习系列之:数组和字符串

1. 基础知识learn

集合:由一个或多个元素构成的整体。就是将一组事物组合在一起。

  • 类型可以不一样
  • 没有顺序要求

列表:又叫线性列表。按照一定顺序排列而成的有限序列。

  • 有序的
  • 长度可变
  • 元素类型可以不同

1.1 数组 

 数组:是列表的实现方式之一。

  • c/c++/java中数组元素类型必须一致,但是python中可以不同,python中数组叫list。
  • 数组有下标索引,但是列表没有
  • 元素连续存储,每个元素占据相同大小的内存空间。列表的可以连续也可以不连续。

1.1.1 数组名的含义 

 数组名的含义:首元素的地址。但是有两个特例:1)sizeof(数组名):表示整个数组所占内存的大小;2)&数组名表示整个数组的地址, + 1会指向数组的尾后地址

数组名是首元素的地址,针对一维int arr[]和二维数组int arr[][]的区别:

  • 一维数组名:因为一维数组的首元素是int,所以一维数组名的类型就是int*,所以使用一维数组做函数参数传递时,实参通常写成int*,即display(int * arr, int size);
  • 二维数组名:因为二维数组首元素是一个一维数组int[column],所以二维数组名的类型就是一个指向一维数组的指针:int (*p_arr)[column]也就是说二维数组名实际不是一维数组,所以不能模仿一维数组的函数传递形式,如果非要模仿就需要把二维数组先转换成真正的一维数组:即,转换成一个一维数组,其元素应该又是一个一维数组,因为函数传递时,一维数组被自动转换成了首元素的地址即int*,所以,二维数组转换后的一维数组的元素的类型应该也是int*, 所以最终二维数组被转换成了int* arr[row]类型,然后这个类型就可以作为参数直接传递给二级指针的形参但是这个转换编译器并没有帮我们实现,需要程序员自己实现。在函数内部就可以当成二级数组进行操作了。

数组的相关操作: 

基于数组的在计算机内存连续存储,有下标索引,且每个元素占内存空间大小相等的特点,来设计数组元素的操作方法。

  • 访问元素“D”的流程:由于我们只保存了数组首元素的地址,所以必须从首元素开始:先找到索引为0的地址2008,再加上索引值2008 + 2 * sizeof(元素类型) =2010,最后间接访问改地址存的元素就是“D”。
  • 插入元素:插入元素需要先腾出空间,然后才可以插入:所以需要先把插入位置的元素及其后面的元素都先向右移动一位,这样子空出来的位置就可以把新元素插入进来
  • 删除元素:删掉后会有一个空位,所以需要把要删元素后面的所有元素都向左移动一位即可。

二维数组:本质上还是一维数组,只是这个一维数组的每个元素又是一维数组。 用来处理矩阵相关的实际问题。

  • 逻辑上是矩阵,由行列逻辑分布,但是在物理内存空间是连续存储的,所以实际跟一个大的一维数组的存储完全相同,所以无果不显示指出column的大小,编译器无法知道每行的数组(一维)的大小。
  • 访问元素:matrix[i][j] = *(*(matrix + i) + j); 更接近计算机语言的理解,仅仅是理解,不一定就是这样子 =  matrix[0][0]的地址 + i * (column * sizeof(type)) + j * sizeof(type)。所以计算机必须要知道行列式的列数,才能找到对应的元素,所以,二维数组作为参数传递时,必须要指明列数。
    a[i][j] = a[ (i) * COLNUM + j ]
  • 二维数组作为参数传递:必须指定二维数组的列数,否则函数无法勾画出二维数组的组织形式。只有有了列长度,通过下标a[i][j]时才能得到正确的下标地址。 二维数组作为参数时,是不能直接使用二级指针作为形参的,因为实际的类型并不匹配,会编译报错。原因如下:二维数组名,实际是一个指向数组的指针,跟真正意义的二级指针还是有些区别的。所以必须严格按照一维数组的方式来改造:即把二维数组改写成一维数组(因为一维数组会被编译器自动转换成指针),该一维数组的元素类型是指向一维数组的指针,所以应该把二维数组名改造成:int * arr[row]。这样子就可以真正的模仿一维数组用一级指针,二维数组用二级指针了。当然了,实际编码时,也可以不用二维数组来表示元素,而是直接使用int * arr[row]形式来初始化二维数组。
形参实参
一维数组display(int * arr, int size)display(数组名,元素个数)
二维数组display(int ** arr, int size)

display(int *arr[row], 总元素个数)

int *arr[row]:arr是一个数组,数组里的每个元素都是int*的指针,所以每个元素都可以指向一个一维数组。

而二维数组名实际是int (*p)[column]的一个指针,该指针又指向了第0行一维数组。所以二维数组名是不可以直接作为二级指针来传递的

二维数组形参形式二维数组实参形式解释说明

display_1(int m[][4], int size) {

// 等价于:(int m[][4], int size_row, int size_column)

调用方式:直接用二维数组名作为形参display_1(matrix, 12);

形参就是二维数组,所以实参可以直接使用二维数组名。

display_2(int (*p)[4], int size)

调用方式:直接用二维数组名作为形参display_1(matrix, 12);

形参实际是一个指针,指向了一个一维数组int[4]。所以形参类型跟二维数组名的类型完全匹配,所以实参可以直接用二维数组名。

displayMatrix(int ** m, int row_size, int column_size)

需要先把二维数组改造成一维数组,其元素时一个指向一维数组的指针:
int *arr[row]; 

for (int i = 0; i < row; i++) {

        arr[i] = matrix[i];
}

形参是一个二级指针,二维数组名虽然可以看成二级指针,但是并不能直接传递给形参,需要先把二维数组完全模仿成一维数组才可以传递给二级指针:即,把二维数组改写成一维数组,该一维数组的元素类型是指向一维数组的指针:一共有row行,所以就有row个指针:int * p[row]

2. 代码demo

 2.1 二维数组demo

//date: 20240404
//author: tianqiang
//二维数组基础 + 作为函数参数
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

//个人觉得,这个并不是很推荐
void displayMatrix(int ** m, int row_size, int column_size) {
    for (int i = 0; i < row_size; i++) {
        for(int j = 0; j < column_size; j++) {
            printf("%d ,", m[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}
//必须提供列数,和元素的总个数
//调用方式:display_1(matrix, 12);
void display_1(int m[][4], int size) {// 等价于:(int m[][4], int size_row, int size_column)
    for (int i = 0; i < size / 4; i++) {
        for(int j = 0; j < 4; j ++) {
            printf("%d ,", m[i][j]);
        }
    }
    printf("\n");
}
//注意:*p一定要用括号括起来,不然编译报错的
//调用方式:display_2(matrix, 12);
void display_2(int (*p)[4], int size) {
    for (int i = 0; i < size / 4; i++) {
        for(int j = 0; j < 4; j ++) {
            printf("%d ,", p[i][j]);
        }
    }
    printf("\n");
}
int main() {
    int matrix[3][4] = {
        {1, 2, 3, 13},
        {4, 5, 6, 16},
        {7, 8, 9, 19}
    };
    display_1(matrix, 12);
    display_2(matrix, 12);
    printf("matrix[0][1] = %d \n", matrix[0][1]);
    printf("&matrix[0][1] = %p \n", &matrix[0][1]);
    printf("matrix[0][1] = %d \n", *(*(matrix + 0)) + 1);

    int *arr[3]; //注意:这里arr是数组,数组的元素是指针。
    for (int i = 0; i < 3; i++) {
        arr[i] = matrix[i];
    }
    //所以可以直接传递arr了,因为这里才是真正意义的把二维数组当成了一维数组来思考的
    displayMatrix(arr, 3, 4);

    return 0;
}

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值