关于指针数组,求解....

bluesnail1986 2011-12-29 07:59:56
#include <stdio.h>

int main(void)
{
char a[15] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
char (*p)[3] = a;
char (*(*q)[3])[4] = a;

printf("%x\n", p[0][1]);
printf("%x\n", q[0][0][1]);

return 0;
}


输出是1和03020104
第一个结果很明白,无疑问。我想问的是第二个输出。为什么打印的不是char?为什么结果是十六进制的03020104?谢了....
...全文
111 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
iamnobody 2011-12-29
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 bluesnail1986 的回复:]
引用 9 楼 anyidan 的回复:

我想知道lz 用什么编译器?

VC6.0,如果觉得不可信可以把代码拷过去run下.....
[/Quote]

我觉得可信,同时也觉得珍爱生命,远离vc6.0.
换个正常点的编译器都不会通过
bluesnail1986 2011-12-29
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 anyidan 的回复:]

我想知道lz 用什么编译器?
[/Quote]
VC6.0,如果觉得不可信可以把代码拷过去run下.....
bluesnail1986 2011-12-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 rabbitlbj 的回复:]

不知道楼主是怎么编译通过的,一个指向15个char的指针如何赋值给一个指向三个char数组的指针??
[/Quote]
在VC下编译通过,结果也是在VC下看到的。如果不信,可以自己把代码复制过去run试下。
这里指针的复制有强制转换,比如char (*p)[3] = a写成char (*p)[3] = char(*)[3] a一样是可以的,我只不过偷了点儿懒而已。
iamnobody 2011-12-29
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zhutou100hao 的回复:]
这个我基本看完了,但是我发现,里面还是有些错误,我个人觉得,可能是作者大意了吧,还有我也觉得你不要一直强调指针不是地址。


引用 4 楼 mingliang1212 的回复:

数组与指针
[/Quote]

这是我在其他帖子里的回复,粘过来的.那时的语境是要强调一下的.

还有你发现哪些错误说出来看看???
AnYidan 2011-12-29
  • 打赏
  • 举报
回复
我想知道lz 用什么编译器?
猪头小哥 2011-12-29
  • 打赏
  • 举报
回复
这个我基本看完了,但是我发现,里面还是有些错误,我个人觉得,可能是作者大意了吧,还有我也觉得你不要一直强调指针不是地址。

[Quote=引用 4 楼 mingliang1212 的回复:]

数组与指针
[/Quote]
如此美丽的你 2011-12-29
  • 打赏
  • 举报
回复
6:        char (*p)[3] = a;//汇编解释为p=&a[0]
00401064 lea eax,[ebp-10h]
00401067 mov dword ptr [ebp-14h],eax
7: char (*(*q)[3])[4] = a; //汇编解释为q=&a[0];
0040106A lea ecx,[ebp-10h]
0040106D mov dword ptr [ebp-18h],ecx //[ebp-18]=&a[0]
8:
9: printf("%x\n", p[0][1]);
00401070 mov edx,dword ptr [ebp-14h]//edx==&a[0]

00401073 movsx eax,byte ptr [edx+1] //[edx+1]=*(a+1)==a[1];
00401077 push eax //这里a[1]入栈,最后输出a[1]的值。
00401078 push offset string "%x\n" (0042201c)
0040107D call printf (004010e0)
00401082 add esp,8
10: printf("%x\n", q[0][0][1]);
00401085 mov ecx,dword ptr [ebp-18h] //ecx=&a[0]
00401088 mov edx,dword ptr [ecx] //错误出现在这里,本应为byte
//这里是dword 取2个字节,执行后edx=03020100h

0040108A add edx,4 //edx=edx+4;
0040108D push edx //最后输出03020104就不足为奇了。
0040108E push offset string "%x\n" (0042201c)
00401093 call printf (004010e0)
00401098 add esp,8


http://blog.csdn.net/neolyao/article/details/7068800

赵老师:
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”


x303383520 2011-12-29
  • 打赏
  • 举报
回复
char (*(*q)[3])[4] = a;改char (*q)[3][4] = a;
q是一个指针,指向a[][3][4]
iamnobody 2011-12-29
  • 打赏
  • 举报
回复
因为不懂楼主问什么,贴个以前的类似的答案给你,,楼上的链接很不错,看看吧
iamnobody 2011-12-29
  • 打赏
  • 举报
回复
iamnobody 2011-12-29
  • 打赏
  • 举报
回复
数组名不是首地址!!
数组名就是代表一个数组.数组名可以隐式转换成首元素的指针(指针不是地址!!!)

数组与指针
其实在C数组都是一维的..


int arr[3];
arr 是数组名,可以隐式转换成首元素的指针,这时元素类型是int,所以可以转换成int*
int* p = arr;//正确.
int*p = &arr[0];//与上面效果一样.

int arr2[3][2];
arr2 是数组名,可以隐式转换成首元素的指针,这时元素类型是int [2];//是一个一维数组.所以可以转换成int(*)[2];//指向数组的指针.

int (*p)[2]=arr2;//正确.
int (*p)[2] = &arr2[0];//与上面效果一样.

===============

引用 15 楼 nanjingnew4 的回复:
你对于*arr是怎么理解的?



*arr;//很明显,数组本身是不存在*(解引用)操作的.于是数组转换成首元素的指针,再被解引用.

*(arr + 0)//这样写也是一样的.不过这里是因为加法操作而转换成指针.


实际上,除了在sizeof(),和&操作之外,其他情况都会转换成指针.

你试试:
int arr[3];
sizeof(arr);
int * p = &arr;//错;
int (*P)[3] = &arr;//对/


对于二维数组:

int arr[3][2];
*arr;//这里跟上面一样,转换成首元素指针,于是*arr表示int [2]数组.

试试:sizeof(*arr) == 8;
int (*)[2] = &*arr ;

**arr;//之所以可以这么写是因为上面转换成来的 int [2];数组还可以再次转换成首元素指针.再次被解引用,实际上这样更直观 *(*arr);

数组名绝不不是就是指针.二维数组名更不是就是二维指针,详见我上面的链接....



RabbitLBJ 2011-12-29
  • 打赏
  • 举报
回复
不知道楼主是怎么编译通过的,一个指向15个char的指针如何赋值给一个指向三个char数组的指针??
bluesnail1986 2011-12-29
  • 打赏
  • 举报
回复
PS:其实我的本意是想都输出1....

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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