当前位置: 首页> 健康> 美食 > 二维数组传参的三种方式

二维数组传参的三种方式

时间:2025/7/14 12:42:04来源:https://blog.csdn.net/2301_77560238/article/details/141391919 浏览次数:0次

提示:文章

文章目录

  • 前言
  • 一、背景
  • 二、
    • 2.1
    • 2.2
  • 总结

前言

前期疑问:
本文目标:


一、背景

问题来源于上次考试做的一道题,题目中是在函数中将字符串分割存在二维数组中。二维数组是从函数外传进来的。但是我还想传出去。传出去的时候就出问题了。基于此,做了一下验证,其中已经写了一篇文章,在文章中验证了多次写法。最后经过多次拉扯,确定了二维数组传参和返回的一些问题。

在这篇文章中做了总结。总结为二维数组传参的三种方法。其中第三种方法还是有问题。

2024年8月21日13:59:47

今天又看了下书《C和指针》,对多维数组相关的知识看了一遍,加深了二维数组的了解,也完善了这篇文章。

二、对二维数组传参的总结

2.1

下面的代码主要是验证数组传参的方式,C和指针书籍Page159也介绍了这两种方式

第一种是DeliverArrayWithSecondPointer(int array[][6], int len)

第二种是int** DeliverArrayWithSecondPointer3(int (*array)[6], int len)

值得一提的是,这边还是验证了返回静态二维数组的方式

下面是具体的代码验证


#include "secondArrayDeliverReturn.h"
#include <stdio.h>int** DeliverArrayWithSecondPointer3(int (*array)[6], int len);int DeliverArrayWithSecondPointer(int array[][6], int len)
{printf("DeliverArrayWithSecondPointer\n");for(int i = 0; i < len; i++){for(int j = 0; j < 6; j++){printf("%d ", array[i][j]);}printf("\n");}printf("\n");for(int i = 0; i < len; i++){for(int j = 0; j < 6; j++){printf("addr:%p ", &array[i][j]);}printf("\n");}printf("\n");for(int i = 0; i < len; i++){printf("addr:%p ", array[i]);}printf("\n");return 0;
}int** DeliverArrayWithSecondPointer2(int array[][6], int len)
{printf("DeliverArrayWithSecondPointer2\n");for(int i = 0; i < len; i++){for(int j = 0; j < 6; j++){printf("%d ", array[i][j]);}printf("\n");}printf("\n");printf("打印全部地址\n");for(int i = 0; i < len; i++){for(int j = 0; j < 6; j++){printf("addr:%p ", &array[i][j]);}printf("\n");}printf("\n");printf("打印首地址\n");for(int i = 0; i < len; i++){printf("addr:%p ", array[i]);}printf("\n");return (int **)array;           //这边直接返回,用二级指针接收,会报错
}int secondArrayDeliverReturn()
{int array[5][6] = {0};for(int i = 0; i < 5; i++){for(int j = 0; j < 6; j++){array[i][j] = i * j;}}DeliverArrayWithSecondPointer(array, 5);int **ptr = DeliverArrayWithSecondPointer2(array, 5);for(int i = 0; i < 5; i++){printf("**ptr addr:%p ", ptr + i);}printf("\n");printf("静态二维数组,形参二维数组指针,返回二级指针,在函数外注意地址访问\n");int **ptr3 = DeliverArrayWithSecondPointer3(array, 5);printf("函数外访问\n");for(int i = 0; i < 6; i++){for(int j = 0; j < 6; j++){printf("addr:%p ", ptr3 + i * 6 + j);}printf("\n");}printf("\n");for(int i = 0; i < 6; i++){for(int j = 0; j < 6; j++){printf("addr:%p ", ptr3[i * j + j]);}printf("\n");}
}//DeliverArrayWithSecondPointer
//0 0 0 0 0 0
//0 1 2 3 4 5
//0 2 4 6 8 10
//0 3 6 9 12 15
//0 4 8 12 16 20
//
//addr:000000c0807ff5a0 addr:000000c0807ff5a4 addr:000000c0807ff5a8 addr:000000c0807ff5ac addr:000000c0807ff5b0 addr:00000
//0c0807ff5b4
//addr:000000c0807ff5b8 addr:000000c0807ff5bc addr:000000c0807ff5c0 addr:000000c0807ff5c4 addr:000000c0807ff5c8 addr:00000
//0c0807ff5cc
//addr:000000c0807ff5d0 addr:000000c0807ff5d4 addr:000000c0807ff5d8 addr:000000c0807ff5dc addr:000000c0807ff5e0 addr:00000
//0c0807ff5e4
//addr:000000c0807ff5e8 addr:000000c0807ff5ec addr:000000c0807ff5f0 addr:000000c0807ff5f4 addr:000000c0807ff5f8 addr:00000
//0c0807ff5fc
//addr:000000c0807ff600 addr:000000c0807ff604 addr:000000c0807ff608 addr:000000c0807ff60c addr:000000c0807ff610 addr:00000
//0c0807ff614
//
//addr:000000c0807ff5a0 addr:000000c0807ff5b8 addr:000000c0807ff5d0 addr:000000c0807ff5e8 addr:000000c0807ff600
// 从打印结果来看,DeliverArrayWithSecondPointer函数内部array变成了指向指针函数的指针一样。或者是按照数组名下标访问//DeliverArrayWithSecondPointer2
//0 0 0 0 0 0
//0 1 2 3 4 5
//0 2 4 6 8 10
//0 3 6 9 12 15
//0 4 8 12 16 20
//
//addr:000000c0807ff5a0 addr:000000c0807ff5a4 addr:000000c0807ff5a8 addr:000000c0807ff5ac addr:000000c0807ff5b0 addr:00000
//0c0807ff5b4
//addr:000000c0807ff5b8 addr:000000c0807ff5bc addr:000000c0807ff5c0 addr:000000c0807ff5c4 addr:000000c0807ff5c8 addr:00000
//0c0807ff5cc
//addr:000000c0807ff5d0 addr:000000c0807ff5d4 addr:000000c0807ff5d8 addr:000000c0807ff5dc addr:000000c0807ff5e0 addr:00000
//0c0807ff5e4
//addr:000000c0807ff5e8 addr:000000c0807ff5ec addr:000000c0807ff5f0 addr:000000c0807ff5f4 addr:000000c0807ff5f8 addr:00000
//0c0807ff5fc
//addr:000000c0807ff600 addr:000000c0807ff604 addr:000000c0807ff608 addr:000000c0807ff60c addr:000000c0807ff610 addr:00000
//0c0807ff614
//
//addr:000000c0807ff5a0 addr:000000c0807ff5b8 addr:000000c0807ff5d0 addr:000000c0807ff5e8 addr:000000c0807ff600
//000000c0807ff5a0 000000c0807ff5a8 000000c0807ff5b0 000000c0807ff5b8 000000c0807ff5c0
// 从打印结果来看,DeliverArrayWithSecondPointer2函数内部将array返回用二级指针接收,会报错。强转之后在函数外部不能正常访问。会丢失二维数组信息。
// 目前静态数组经过传参再返回,只有在函数内部创建一个指针数组,再返回指针数组的地址,用二级指针接收可以实现。
// 还有一个问题就是二维数组传参,二维数组指针作为形参之前写的不对
// 下面验证一下int** DeliverArrayWithSecondPointer3(int (*array)[6], int len)
{printf("DeliverArrayWithSecondPointer3\n");for(int i = 0; i < len; i++){for(int j = 0; j < 6; j++){printf("%d ", array[i][j]);}printf("\n");}printf("\n");for(int i = 0; i < len; i++){for(int j = 0; j < 6; j++){printf("addr:%p ", &array[i][j]);}printf("\n");}printf("\n");for(int i = 0; i < len; i++){printf("addr:%p ", array[i]);}printf("\n");return (int **)array;
}// DeliverArrayWithSecondPointer3打印信息
//尝试直接返回静态二维数组强制转换的二级指针,在函数外注意地址访问,是会出错的。出错的点在于即便我使用形如ptr3 + i * 6 + j方式,偏移的长度是64位指针长度8,而二维数组的偏移是4
//静态二维数组,形参二维数组指针,返回二级指针,在函数外注意地址访问
//DeliverArrayWithSecondPointer3
//0 0 0 0 0 0
//0 1 2 3 4 5
//0 2 4 6 8 10
//0 3 6 9 12 15
//0 4 8 12 16 20
//
//addr:0000009b6d5ff880 addr:0000009b6d5ff884 addr:0000009b6d5ff888 addr:0000009b6d5ff88c addr:0000009b6d5ff890 addr:00000
//09b6d5ff894
//addr:0000009b6d5ff898 addr:0000009b6d5ff89c addr:0000009b6d5ff8a0 addr:0000009b6d5ff8a4 addr:0000009b6d5ff8a8 addr:00000
//09b6d5ff8ac
//addr:0000009b6d5ff8b0 addr:0000009b6d5ff8b4 addr:0000009b6d5ff8b8 addr:0000009b6d5ff8bc addr:0000009b6d5ff8c0 addr:00000
//09b6d5ff8c4
//addr:0000009b6d5ff8c8 addr:0000009b6d5ff8cc addr:0000009b6d5ff8d0 addr:0000009b6d5ff8d4 addr:0000009b6d5ff8d8 addr:00000
//09b6d5ff8dc
//addr:0000009b6d5ff8e0 addr:0000009b6d5ff8e4 addr:0000009b6d5ff8e8 addr:0000009b6d5ff8ec addr:0000009b6d5ff8f0 addr:00000
//09b6d5ff8f4
//
//addr:0000009b6d5ff880 addr:0000009b6d5ff898 addr:0000009b6d5ff8b0 addr:0000009b6d5ff8c8 addr:0000009b6d5ff8e0
//函数外访问
//addr:0000009b6d5ff880 addr:0000009b6d5ff888 addr:0000009b6d5ff890 addr:0000009b6d5ff898 addr:0000009b6d5ff8a0 addr:00000
//09b6d5ff8a8
//addr:0000009b6d5ff8b0 addr:0000009b6d5ff8b8 addr:0000009b6d5ff8c0 addr:0000009b6d5ff8c8 addr:0000009b6d5ff8d0 addr:00000
//09b6d5ff8d8
//addr:0000009b6d5ff8e0 addr:0000009b6d5ff8e8 addr:0000009b6d5ff8f0 addr:0000009b6d5ff8f8 addr:0000009b6d5ff900 addr:00000
//09b6d5ff908
//addr:0000009b6d5ff910 addr:0000009b6d5ff918 addr:0000009b6d5ff920 addr:0000009b6d5ff928 addr:0000009b6d5ff930 addr:00000
//09b6d5ff938
//addr:0000009b6d5ff940 addr:0000009b6d5ff948 addr:0000009b6d5ff950 addr:0000009b6d5ff958 addr:0000009b6d5ff960 addr:00000
//09b6d5ff968
//addr:0000009b6d5ff970 addr:0000009b6d5ff978 addr:0000009b6d5ff980 addr:0000009b6d5ff988 addr:0000009b6d5ff990 addr:00000
//09b6d5ff998
//
//addr:0000000000000000 addr:0000000000000000 addr:0000000000000000 addr:0000000100000000 addr:0000000300000002 addr:00000
//00500000004
//addr:0000000000000000 addr:0000000000000000 addr:0000000300000002 addr:0000000200000000 addr:0000000a00000008 addr:00000
//00900000006
//addr:0000000000000000 addr:0000000100000000 addr:0000000200000000 addr:0000000300000000 addr:0000000400000000 addr:00007
//ff6198ceff7
//addr:0000000000000000 addr:0000000300000002 addr:0000000a00000008 addr:0000000400000000 addr:0000009b6d5ff880 addr:00000
//00500000006
//addr:0000000000000000 addr:0000000500000004 addr:0000000900000006 addr:00007ff6198ceff7 addr:0000000500000006 addr:00007
//ff6198cf4f7
//addr:0000000000000000 addr:0000000200000000 addr:0000000400000000 addr:000000036d5ff958 addr:0000009b6d5ff9d0 addr:00000
//00000000001

2.2

三、静态二维数组返回方式

静态二维数组返回方式目前看只有一种,就是在函数内存创建静态指针数组,将二维数组的首地址赋值给指针数组,然后使用二级指针返回,在函数外部解析地址。

四、指针+1的概念

还是疑惑为什么函数DeliverArrayWithSecondPointer3返回二级指针ptr3,对ptr3进行+1操作偏移地址为8,为什么不是偏移4,偏移4的话就能正确访问二维数组了,下面代码是验证这一问题

printf("打印二级指针+1的地址\n");
printf("%p\n",ptr3);
printf("%p\n",ptr3 + 1);
printf("sizeof(ptr3):%d\n",sizeof(ptr3));//打印结果
//打印二级指针+1的地址
//000000f3b33ff980
//000000f3b33ff988
//sizeof(ptr3):8

查找资料,指针+1偏移的长度取决于指针指向的数据类型是什么。


总结

未完待续

关键字:二维数组传参的三种方式

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: