二维数组形参传递问题

zhangwujian 2007-04-29 12:09:14
在传递二维数组的时候我使用了指针的强制类型转换来测试打印功能,可是我发现在函数中并没有按照我写的那样去做,只是第一行打印正确,请问各位为什么?
源码如下:
#include <iostream>
#include <string>
using namespace std;

void select_min(int** a_time,int m,int n){

for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
cout<<*((int*)(a_time+i)+j)<<endl;
}
}
return ;
}

int main(){
int all_time[100][100];
int i,j;
int m=2;
int n=2;
for(i=0;i<m;i++)
{
for (j=0;j<n;j++)
{
all_time[i][j]=i*2+j;
}
}
for(i=0;i<2;++i)
{
for(j=0;j<n;++j)
{
cout<<*((int*)(all_time+i)+j)<<endl;
}
}
select_min((int**)all_time,m,n);
system("pause");
return 0;
}

...全文
810 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangyq73 2007-04-30
  • 打赏
  • 举报
回复
二维数组其实可以就是一维数组,没那复杂
jackyyvan 2007-04-29
  • 打赏
  • 举报
回复
void select_min(int** a_time,int m,int n){
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{

long pos=(long)a_time+(i*100*sizeof(int)+j*sizeof(int));//得到数组元素地址
int val;
memcpy(&val,(int**)pos,sizeof(int));//把该地址的int复制到变量中
cout<<val<<" ";//输出
}
cout<<endl;
}
return ;
}
rubypan 2007-04-29
  • 打赏
  • 举报
回复
cout<<*((int*)(all_time+i)+j)<<endl;

这句有两个问题
rubypan 2007-04-29
  • 打赏
  • 举报
回复
//cout<<*((int*)(a_time)+i*100+j)<<endl;
//cout<<*((int*)(a_time+i*100+j))<<endl;
//这两个是等价的,推荐第一个,更符合人类心理

只有第一个可以,第二个不对
rubypan 2007-04-29
  • 打赏
  • 举报
回复
#include <iostream>
#include <string>
using namespace std;

void select_min(int* a_time,int m,int n){
//转换为一维数组
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
cout<<*((a_time+i*100)+j)<<" ";//形参数组对应的实参数组的第二维参数
}
cout<<endl;
}
return ;
}

void select_min1(int a_time[][100],int m,int n){
//如果要用多维数组,除第一位以外的数组维数必须给出
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
cout<<a_time[i][j]<<" ";
}
cout<<endl;
}
return ;
}

int main(){
int all_time[100][100];
int i,j;
int m=2;
int n=2;
for(i=0;i<m;i++)
{
for (j=0;j<n;j++)
{
all_time[i][j]=i*2+j;
}
}
for(i=0;i<m;++i)
{
for(j=0;j<n;++j)
{
//cout<<*((int*)(all_time+i*100)+j)<<endl;
cout<<all_time[i][j]<<" ";//有数组的形式

}
cout<<endl;
}
select_min(&all_time[0][0],m,n);
select_min1(all_time,m,n);//这两者效果一样
system("pause");
return 0;
}
zhangwujian 2007-04-29
  • 打赏
  • 举报
回复
昨天晚上躺在床上之后我还在想这个问题,突然之间才恍然大悟,想起我同学的一句经典的话:编译器是很愚蠢的!呵呵,确实如此,向函数传递形参的时候,编译器忽视掉了数组的信息,而在主程序中使用cout<<*((int*)(all_time+i)+j)<<endl的时候,编译器知道数组每维的大小,所以all_time+i的时候自动指向下一“行”,但是传递到函数内部的时候就会丢失了,要指定指针的大小。
修正如下:
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

void select_min(int** a_time,int m,int n){

for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
//a_time是一个指向int类型指针的指针
//a_time只是他包含的指针的地址,第一个首地址的信息,并不知道
// ├──────┤ |-------------| |---------|
// │a_time │--> |int类型的指针|-->|int值 |
// ├─┄┄┄┄─┤ |-------------| |---------|

//这里的a_time+i表示按照int*类型顺序向下寻址
//所以
//cout<<*((int*)(a_time)+i*100+j)<<endl;
//cout<<*((int*)(a_time+i*100+j))<<endl;
//这两个是等价的,推荐第一个,更符合人类心理

//失败的实验
//cout<<*((int*)(a_time+i*(sizeof(int)*100))+j)<<endl;
//cout<<*(int*)(a_time+i*sizeof(int)*100+j*sizeof(int))<<endl;
//printf("%d\n",*(a_time+i*(sizeof(int)*100)+j*sizeof(int)));

// 成功
cout<<*((int*)(a_time)+i*100+j)<<endl;
//cout<<*((int*)(a_time+i*100+j))<<endl;
}
}
return ;
}

int main(){
int all_time[100][100];
int i,j;
int m=2;
int n=2;
for(i=0;i<m;i++)
{
for (j=0;j<n;j++)
{
all_time[i][j]=i*2+j;
}
}
for(i=0;i<2;++i)
{
for(j=0;j<n;++j)
{
//all_time是一个指向100个int类型的一维数组
//这里的all_time就是这个一维数组的首部地址
//所以all_time+i表示第几行的首部地址
//假如int x[4][3]={{1,2,3},{5,6,7},{9,10,11},{13,14,15}};
//int (*p)[3];
//├──────┤← p
//│a[0][0] │
//├─┄┄┄┄─┤
//│a[0][1] │
//├─┄┄┄┄─┤
//│a[0][2] │
//├──────┤← p+1
//│a[1][0] │
//├─┄┄┄┄─┤
//│a[1][1] │
//├─┄┄┄┄─┤
//│a[1][2] │
//├──────┤← p+2
//│a[2][0] │
//├─┄┄┄┄─┤
//│a[2][1] │
//├─┄┄┄┄─┤
//│a[2][2] │← *((int *)(p+2)+2)
//├──────┤← p+3
//│a[3][0] │
//├─┄┄┄┄─┤
//│a[3][1] │
//├─┄┄┄┄─┤
//│a[3][2] │
//├──────┤

cout<<*((int*)(all_time+i)+j)<<endl;
}
}
select_min((int**)all_time,m,n);
system("pause");
return 0;
}

感谢rulary(秦枫),虽然你的答案是错的,因为c/c++保证了按照指针所指向类型计算其指针的增减,欢迎大家继续讨论
rularys 2007-04-29
  • 打赏
  • 举报
回复


cout<<*((int*)(all_time+i)+j)<<endl;
改为:
cout<<*((int*)(all_time+i*(sizeof(int)*100))+j)<<endl;

这个做法比较危险 ,: )
rularys 2007-04-29
  • 打赏
  • 举报
回复

我的是错的,哈哈,对不住咯 ~下不为例
zhangwujian 2007-04-29
  • 打赏
  • 举报
回复
果真是没有交流就没进步,感谢大家都很热情
to rubypan()
两种方法都可以我在vc和dev都有实验,原理我已经在注释中解释
to jackyyvan()
可以用cout<<**(int**)pos<<endl;//输出

65,212

社区成员

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

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