求助:C++ 形参是二维数组

proof1 2016-09-18 05:15:46
函数形参不可改动:

void MaxSum(int m, int n, int **a ) {
a[1][1]=8 ;
}



主程序调用:

int main() {
int m=3,n=4;
int b[3][4]={{ 7 , 23, -32, 6 }, // 必须批量斌值,不可单个斌值
{ -19, 6, 32, -9 },
{ -2 , 11, -4, 13 } };

MaxSum(m,n,(int **)b);
}


如何做较少的改动,能够调用成功?
...全文
216 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
proof1 2016-09-19
  • 打赏
  • 举报
回复
提这个问题的原因是:教材上有这个例程,其中 **a 是一个矩阵。但没有给出主程序:

void MaxSum(int m, int n, int **a ) {
	
}
自己编写的主程序,矩阵赋值时,当然希望是直观的方块形状。
proof1 2016-09-19
  • 打赏
  • 举报
回复
引用 1 楼 paschen 的回复:
如果函数参数不能改变,那么你只能在函数中根据m,n计算a[1][1]的位置,然后赋值 直接调用a[1][1]是不行的
实参形式可以改动。 函数形参,特别是第3个形参“int **a”,不可改动。

void MaxSum(int m, int n, int **a ) {
	
}
而主程序调用语句的实参,可自由改动,不必拘泥“(int **)b”形式。

int main() {
	MaxSum( m, n,  (int **)b );
} 
这样的话,有办法直接a[1][1]吗?
清海风缘 2016-09-18
  • 打赏
  • 举报
回复
修改一处笔误:

当然就不能按照二维 指针[][]的方式访问其元素.
应该为:
当然就不能按照二维 数组[][]的方式访问其元素.
清海风缘 2016-09-18
  • 打赏
  • 举报
回复

一步步讲解, 首先 b[3][4]中的元素在内存中的存放顺序如下:
{7 , 23, -32, 6 , -19, 6, 32, -9 , -2 , 11, -4, 13 };

(int **)b, 将二维数组b强制转换为了二级指针a, 也就是说通过函数
参数传递, 二维数组蜕化为了二维指针

回忆下学习C语言多级指针时的知识, 提个问题: 如何访问多级指针?
这里为如何访问二级指针?

示例:

int age = 25;
int* pAge = &age;
int** ppAge = &pAge;

请问,如何通过 ppAge 输出 age 的值?

// 对ppAge"提领"两次即可, 简单吧
printf("age: %d", **p);

// 再详细一点
printf("age: %d", *(*p));


那么, 我们来看看上面 二级指针a[1][1]的访问过程:

上面说了, a 指向的内存布局如下:
{7 , 23, -32, 6 , -19, 6, 32, -9 , -2 , 11, -4, 13 };

所以,
a[1], 即: *(a+1) : 指针指向 "23", 假设 存贮"23"变量的内存地址(即: 23的指针)为A

a[1][1], 即: *(*(a+1) + 1), 也就是: *(*A + 1)

而 *A == 23, 从而
a[1][1] 等价于: *(*A + 1) 等价于: *(23 + 1) 等价于: *(24)

看见了没, a[1][1]的操作是对地址为24( 十六进制: 0x00000018)的内存进行访问,
肯定访问越界, 程序终止.

为什么会这样, 因为二维指针蜕化为二级指针后, 其类型信息就丢失了. 当然就不能按照
二维指针[][]的方式访问其元素.

改正代码1:

#include <cstdio>

typedef int TwoDimenArray[3][4];

void MaxSum(int m, int n, TwoDimenArray* a ) {
TwoDimenArray& myArray = (TwoDimenArray&)(*a);
printf("myArray[1][1]: %d\n", myArray[1][1]);

myArray[1][1] = 8;
}

int main() {
int m=3,n=4;
TwoDimenArray b ={{ 7 , 23, -32, 6 }, // 必须批量斌值,不可单个斌值
{ -19, 6, 32, -9 },
{ -2 , 11, -4, 13 } };

printf("b[1][1]: %d\n", b[1][1]);

MaxSum(m,n, &b);

printf("b[1][1]: %d\n", b[1][1]);
}

改正代码2:

// 推荐使用C++11 std::array

#include <cstdio>
#include <array>

typedef std::array<int, 4> OneDimenArray;
typedef std::array<OneDimenArray, 3> TwoDimenArray;

void MaxSum(int m, int n, TwoDimenArray* a ) {
TwoDimenArray& myArray = (TwoDimenArray&)(*a);
printf("myArray[1][1]: %d\n", myArray[1][1]);

myArray[1][1] = 8;
}

int main() {
int m=3,n=4;
TwoDimenArray b = {
OneDimenArray{ 7 , 23, -32, 6 }, // 必须批量斌值,不可单个斌值
OneDimenArray{ -19, 6, 32, -9 },
OneDimenArray{ -2 , 11, -4, 13 }
};

printf("b[1][1]: %d\n", b[1][1]);

MaxSum(m,n, &b);

printf("b[1][1]: %d\n", b[1][1]);
}
赵4老师 2016-09-18
  • 打赏
  • 举报
回复
请那些喜欢将数组作为函数参数传来传去或作为函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或作为函数返回值呢?
paschen 版主 2016-09-18
  • 打赏
  • 举报
回复
如这样表示的就是 a[1][1],其他同理
void MaxSum(int m, int n, int **a ) {
	*((int*)a+1*n+1)=8;
}

int main() {
	int m=3,n=4;
	int b[3][4]={{  7 , 23, -32,  6 },               // 必须批量斌值,不可单个斌值
	{ -19,  6,  32, -9 },
	{ -2 , 11,  -4, 13 } };

	MaxSum(m,n,(int **)b);
} 
paschen 版主 2016-09-18
  • 打赏
  • 举报
回复
如果函数参数不能改变,那么你只能在函数中根据m,n计算a[1][1]的位置,然后赋值 直接调用a[1][1]是不行的

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧