二维指针问题(急!!!)

me1001 2009-04-20 11:50:22
这样写,运行时出错。
#include "stdafx.h"
#include<iostream.h>

int main(int argc, char* argv[])
{

int a[2][2]={{1,2},{3,4}};
int **p=(int**)a;

for(int i=0;i<2;i++)
for(int j=0;j<2;j++)


cout<<p[j][i]<<endl;
return 0;
}


而这样写,就没错,上面的代码到底错在哪里?
#include "stdafx.h"
#include<iostream.h>


int main(int argc, char* argv[])
{

int a[2][2]={{1,2},{3,4}};



for(int i=0;i<2;i++)
for(int j=0;j<2;j++)


cout<<a[j][i]<<endl;
return 0;
}
...全文
286 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
机智的呆呆 2009-04-20
  • 打赏
  • 举报
回复

#include<iostream>
using namespace std;

template<typename T,int M,int N>
void GetLine(T (&a)[M][N])
{
for(int i=0;i <M;i++)
for(int j=0;j <N;j++)
cout <<a[i][j] <<endl;

}

int main()
{
int a[2][2]={{1,2},{3,4}};
int b[3][3]={0,1,2,3,4,5};

GetLine<int,2,2>(a);
GetLine<int,3,3>(b);
system("pause");
}


0黄瓜0 2009-04-20
  • 打赏
  • 举报
回复
为什么a[j][i] 可以,而p[j][i]不行,这也体现指针和数组的不同。a[j][i]是编译时计算偏移,访问位置编译时就已经确定,而p[j][i]是运行时根据指针变量p中保存的地址,然后对这个地址进行j个指针的偏移,在那儿又保存了一个地址,根据第二次找到的地址,再在这个地址之上进制i个数据类型的偏移,最后才找到需要的数据。
wllenyj 2009-04-20
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 WOBUGUAN 的回复:]
形参可以直接写作:
void GetLine(int a[10][10]);

调用的时候可以用:
int a[10][10];
GetLine(a);
[/Quote]

功能是实现了,那这个函数可就太垃圾了-_-!
0黄瓜0 2009-04-20
  • 打赏
  • 举报
回复
二级指针和二维数组:
第一层理解:
void f(){
char a[10][10] ;//这条语句在栈上分配10*10=100个char型元素的内存,通常是100字节
char **p; //这条语句在栈上分配可以存一个内存地址的内存,通常为4字节。
}

第二层理解:
void f(){
char a[10][10] ;//a代表那100字节内存的首地址。
char **p; //p表示的内存中存放了一个地址,用这个地址找到内存的另一个地方存放的仍是一个地址,再用这第二个地址找到内存的第三个地方,存放着一个char型数据。
}

第三层理解:
void f(){
char a[10][10] ;//a[0],a[1]仍然是代表一段内存的首地址。
char **p; //如果忽视数据类型:p=a是正确的,因为把一个内存地址放入一个指针变量是天经地义的。但若考虑数据类型,p=a是错误的。因为此时*p取到的是a[0][0]处的数据,按p的定义,此时a[0][0]处应该保存一个内存地址(而且如果保存内存地址将跨越a[0][0]到a[0][3]),但是事实上那里保存的是char数据,如果强制使用**P去找一个char数据,将会是一个非法内存访问(把a中的字符当成地址了)。
}

第四层理解:
#include <stdio.h> 
#include <stdlib.h>

void f(){
char a[11][8] ;//
char **p; //

const int cou=sizeof(a)/sizeof(a[0]);//用二维数组所站空间的大小除以其中一维所站空间的大小,计算出这个二维数组中包含多少个一维数组。
printf("***%d***\n",cou);
p=(char**)malloc(sizeof(char*)*cou);//一个内存地址放入一个指针变量是天经地义的

for(int i=0;i<cou;i++)
{
p[i]=a[i];//因为已经给p分配了指向,且是cou个元素的内存,所以使用p[0]到p[cou-1]可以合法访问这段内存。
//因为a[0],a[1]也是代表一段内存的地址,把它存入类型为char*的内存中是没有问题的(p[i]的类型为char*).
//此后*p访问到的是malloc分配的那段内存之首,而且那里存放的是一个地址,也就是a[0]所代表的地址,其值与&a[0][0]相同。
for(int j=0;j<sizeof(a[0]);j++)
{
p[i][j]=65+i+j;//这里的**p与p[0][0]等价,p[0][1]就是(*p)[1]也就是*(*p+1),总之p[i][j]就是*(*(p+i)+j),晕了吧,我也可能会晕了写错。
//从简单的来推一下:char arr[10]; arr[0]就是*(arr+0),arr[1]就是*(arr+1),也就是数组的下标是相对于数组首地址的偏移,理解c的下标为什么要从0开始了吧
//从简单到复杂,与上行同理p[i]就是*(p+i),p[i][j]就是(*(p+i))[j],就是*(*(p+i)+j)。
}
}
for(int c=0;c<cou;c++)
{
for(int d=0; d<sizeof(a[0]);d++)
{
printf("%c,",p[c][d]);
}
printf("\n");
for(int e=0; e<sizeof(a[0]);e++)
{
printf("%c>",*(*(p+c)+e));//这样访问输出给你比较
}
printf("\n");

}

}

int main()
{

f();
return 0;

}


第五层理解。
指针和数组不相同。
指针变量本身有个保存的地方,这个地方保存另一个地方的地址(这就是指针的指向),也就是指针变量除了类型,与其他变量其实是一样的。数组名代表一段内存的首地址,但这个地方保存的是数组元素。

  • 打赏
  • 举报
回复
[Quote=引用 16 楼 xusuai5820016 的回复:]
这种情况如何处理?

定义并初始化了一个二维数组 a[10][10];

如果写了一个函数 void GetLine(),这个函数的功能是输出 二维数组a里面的元素;

void GetLine(形参)
{
for(int i=0;i <10;i++)
for(int j=0;j <10;j++)

cout < <p[i][j] < <endl;

}

那么这个函数的形参应该怎么写啊?调用该函数的时候,实参又该怎么写?
[/Quote]
楼主你认真看回帖,好不?11,12楼.
WOBUGUAN 2009-04-20
  • 打赏
  • 举报
回复
形参可以直接写作:
void GetLine(int a[10][10]);

调用的时候可以用:
int a[10][10];
GetLine(a);

me1001 2009-04-20
  • 打赏
  • 举报
回复
这种情况如何处理?

定义并初始化了一个二维数组 a[10][10];

如果写了一个函数 void GetLine(),这个函数的功能是输出 二维数组a里面的元素;

void GetLine(形参)
{
for(int i=0;i <10;i++)
for(int j=0;j <10;j++)

cout < <p[i][j] < <endl;

}

那么这个函数的形参应该怎么写啊?调用该函数的时候,实参又该怎么写?
fallening 2009-04-20
  • 打赏
  • 举报
回复
强制转换失败,没有办法,不匹配
fallening 2009-04-20
  • 打赏
  • 举报
回复
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{

int a[2][2]={{1,2},{3,4}};
int* p = (int*) a;


for(int i=0;i <2;i++)
for(int j=0;j <2;j++)
cout <<p[j+i] <<endl;
return 0;
}
fallening 2009-04-20
  • 打赏
  • 举报
回复
#include <iostream.h>

int main(int argc, char* argv[])
{

int a[2][2]={{1,2},{3,4}};
int **p=(int**)a;

for(int i=0;i <2;i++)
for(int j=0;j <2;j++)


cout < <p[j][i] < <endl;
return 0;
}
  • 打赏
  • 举报
回复
调用的时候

a[10][10];
GetLine(a);
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 xusuai5820016 的回复:]
这种情况如何处理?

定义并初始化了一个二维数组 a[10][10];

如果写了一个函数 void GetLine(),这个函数的功能是输出 二维数组a里面的元素;

void GetLine(形参)
{
for(int i=0;i <10;i++)
for(int j=0;j <10;j++)

cout < <p[i][j] < <endl;

}

那么这个函数的形参应该怎么写啊?调用该函数的时候,实参又该怎么写?
[/Quote]

void GetLine(int *p[10])
{
for(int i=0;i <10;i++)
for(int j=0;j <10;j++)

cout < <p[i][j] < <endl;

}
me1001 2009-04-20
  • 打赏
  • 举报
回复
这种情况如何处理?

定义并初始化了一个二维数组 a[10][10];

如果写了一个函数 void GetLine(),这个函数的功能是输出 二维数组a里面的元素;

void GetLine(形参)
{
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)

cout<<p[i][j]<<endl;

}

那么这个函数的形参应该怎么写啊?调用该函数的时候,实参又该怎么写?


wl_99888 2009-04-20
  • 打赏
  • 举报
回复
int a[2][2]={{1,2},{3,4}};
int *p = (int *)a;

for(int i=0;i <2;i++)
for(int j=0;j <2;j++)

cout << *(p + i + j)<<endl;
wllenyj 2009-04-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hairetz 的回复:]
因为2维指针跟2维数组不等效.
参看数组名不完全等于指针
http://blog.csdn.net/rjzou2006/archive/2008/04/15/2292698.aspx

2维数组动态分配,参看
http://blog.csdn.net/jia_xiaoxin/archive/2008/11/10/3268645.aspx
[/Quote]


谢了谢了
lingyin55 2009-04-20
  • 打赏
  • 举报
回复

int main(int argc, char* argv[])
{

int a[2][2]={{1,2},{3,4}};
int (*p)[2] = a; //改下这里

for(int i=0;i <2;i++)
for(int j=0;j <2;j++)


cout << p[j][i] <<endl;
return 0;
}
liliangbao 2009-04-20
  • 打赏
  • 举报
回复
int (*p)[2] = a;
这样定义p表示指向长度为2的数组指针~
而 int **p;
表示指针的指针,类型不对了~
  • 打赏
  • 举报
回复
因为2维指针跟2维数组不等效.
参看数组名不完全等于指针
http://blog.csdn.net/rjzou2006/archive/2008/04/15/2292698.aspx

2维数组动态分配,参看
http://blog.csdn.net/jia_xiaoxin/archive/2008/11/10/3268645.aspx
wllenyj 2009-04-20
  • 打赏
  • 举报
回复
我也遇到了相同的问题,按理说**应该能指想2维数组啊

还有就是数组名不能给引用传参,比如:
void fun(const int &ra){...}
int main(){
int a[10]={0};
fun(a);
}
这样好像也不行.哪位大大能给解释下啊。
还有就是2维数组的内存分配是怎样的??
mengde007 2009-04-20
  • 打赏
  • 举报
回复

int (*p)[2]=a;

//二维指针和二维数组是不等价的。
加载更多回复(6)

64,682

社区成员

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

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