C语言_补习填坑_数据处理_二维(字符)数组的指针问题以及传参

背景

最近快开学了,寒假一直在学习SQL、前端、Flask等。C语言忘得也差不多了。
之前对于二维字符数组一直有一些疑问,最近在做C语言作业的时候问题就暴露出来了。
于是开此篇记录一下学习。

关于二维字符数组

1、声明(初始化)

对比Pyhon记忆

str_list=['abc','def','ghi']

C中

char str_list[3][4]={"abc","de","fg"};

char str_list[][4]={"abc","de","fg"};

注意:

  • 第二维的大小(可省略)>=第二维中最长字符串长度+1
    (上方"abc"的长度为3,则第二维设为>=4)
  • 第一维的大小>=后方{}中的元素个数即可。

对于二维字符数组的定义探究

//指定二维(最小)
char str_list1[][4]={"abc","def","ghi"};
printf("长度1:%d\n",sizeof(str_list1));

//指定二维(更大) 
char str_list2[][100]={"abc","def","ghi"};
printf("长度2:%d\n",sizeof(str_list2));

//指定一维二维
char str_list3[100][4]={"abc","def","ghi"};
printf("长度3:%d\n",sizeof(str_list3));

输出如下:

长度1:12
长度2:300
长度3:400

从上面的探究可以看出。初始化时二维数组的第一维大小之所以可省略,是因为编译器自动确认了后方{}内的元素个数。

但为何第二维大小不可省略呢?

我们知道,二维数组在内存中的储存方式等价于一维数组,即str_list[3][4]等价于str_list[12](只不过第二种方法不能用str_list[i][j]的方式读取其中储存的元素)

第二维的大小可以说是二维数组的灵魂,只要定义时有了第二维的大小,即可将一维数组等长折叠(可以形象的理解为换行)起来变成二维数组。

我们可以这么理解,第二维的大小指定了一维数组应该怎么折叠变成二维数组,一旦第二维的大小没有指定,折叠的方式就没有完全确定,程序语言是严谨的,所以第二维大小必须要确定。

2、二维字符数组的指针

本来写博客的时候想写个示例程序的,结果把自己又绕晕了,先挖个坑。。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    //声明二维
    char str_list1[][4]={"abc","def","ghi"};

    //打印第一行的几种方式
    printf("1%s\n",str_list1);   //二维数组名称,char (*)[4]
    printf("2%s\n",*str_list1);     //对名称取值,char *
    printf("3%s\n",&str_list1);      //对名称取地址,char (*)[3][4]
    printf("4%s\n",str_list1[0]);        //首行地址, char *
//    printf("%s\n",*(str_list1[0]));
    printf("5%s\n",&str_list1[0]);            //对首行地址取地址,char (*)[4]
    printf("6%s\n",&(str_list1[0]));           //对首行地址取地址, char (*)[4]
    printf("7%s\n",(&str_list1)[0]);           //对名称取地址后取第一, char (*)[4]
    printf("8%s\n",&str_list1[0][0]);            //对首行首字母取地址, char *

    printf("\n");
    return 0;
}

有待继续研究

3、二维字符数组传参

最近写了一个split函数,通过分隔符分割str,然后将分割结果储存在二维字符数组中。

注意!!!
其中第三个参数为一个二维指针数组,例a[100][80]

// 分割文本,返回分割出的数量
int Split(char *str, char *delim, char (*array)[100]) {

    /* 获取第一个子字符串 */
    char *token;
    token = strtok(str, delim);

    int i = 0;
    /* 继续获取其他的子字符串 */
    while (token != NULL) {
        strcpy(*(array+i), token);
        i++;
        token = strtok(NULL, ",");
    }

    return i;
}

*(array+i)可替换为array+iarray[i]

研究了很久最终写出以上代码,主要问题在二维字符数组的实参传递上。

※难点①(区分数组指针、指针数组、二级指针)

  • char (*array)[80]——声明一个指向字符数组指针数组
    其中:
    arrayarray[0],指向第一个(行)char[80]
    array+iarray[i],指向第i+1行(个)char[80]

  • char *array[100]——由于[]优先级更高,不加括号是一个指向单个字符指针数组
    其中:
    array为第一个指向一个字符的指针

  • char* (*array)[100]——声明一个指向字符指针数组指针数组(二级指针)。
    其中:
    array,指向第一个(行)char *[80]
    array+n,指向第n+1行(个)char *[80]

※难点②(指向字符数组的指针数组解引用)
后来写博客的时候发现,也不是这么难,主要是理解上面的指针区别。
记住以下等价即可

*(array+i)可替换为array+iarray[i]

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值