大神何在...关于指针的一项困惑

sxyryin 2011-09-21 09:10:29
程序1:
#include <stdio.h>

int main()
{
char planets[9][8] = {"Mercury","Venus","Earth",
"Mars","Jupiter","Saturn",
"Uranus","Nepturn","Pluto"};
int i;

for (i = 0;i < 9;i++)
{
printf("%s\n",planets[i]);
printf("%s\n",&planets[i]);
}

return 0;
}

planets[i]是指针,那&planets[i]就是指针的指针,那为嘛两个printf的输出一模一样??
输出结果如下:
Mercury
Mercury
Venus
Venus
Earth
Earth
Mars
Mars
Jupiter
Jupiter
Saturn
Saturn
Uranus
Uranus
Nepturn
Nepturn
Pluto
Pluto
程序2:
#include <stdio.h>

int main()
{
char planets[9][8];
int i;

for (i = 0;i < 9;i++) //这里改用手工录入
{
printf("Enter string %d: ",i+1);
scanf("%s",planets[i]);
}
/*
for (i = 0;i < 9;i++) //这里改用手工录入
{
printf("Enter string %d: ",i+1);
scanf("%s",&planets[i]); //这里scanf函数第二个参数为&planets[i]
}
*/

for (i = 0;i < 9;i++)
{
printf("%s\n",planets[i]);
printf("%s\n",&planets[i]);
}


return 0;
}

无论是用程序2中的for循环录入,还是用程序2中被注释部分的for循环录入,都可以实现将字符串存入二维数组中,而且下面的printf函数一样正常输出

问题就来了,到底是就这两个函数特殊,还是只要是用二维数组存储字符串集,难道planets[i]与&planets[i]效果都一样???
大神现身....
...全文
168 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2011-09-22
  • 打赏
  • 举报
回复
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!
radiohead001 2011-09-22
  • 打赏
  • 举报
回复
a[10] = "abc";
&a[0] 这个效果和直接用“a”是一样的。
sxyryin 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 fs1360472174 的回复:]

我想问楼主一句:你输出此句printf("%d",a);a已定义,这里你a输出时用了指针?
[/Quote]
但不可否认的是输出字符串时用了指针,那是对printf的实际实现不了解?呵呵,俺还是初学者...
sxyryin 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 wangbishi22 的回复:]

C语言中其实是没有多维数组这个概念的,有的只是数组中嵌套数组。
int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
可以分解为
a[0] 相当于是 {0,1,2,3} 这个数组的数组名

同一楼所说的,数组名和对此数组名取地址,得到的结果是一样的。
[/Quote]
如果这么推的话,那a[0]与&a[0][0]是相等的,这个可以理解,但程序1,2中都是用a[0]与用&a[0]效果一样,这又怎么解释呢?难道二维数组里a[0]与&a[0][0]与&a[0]都可互换使用?
sxyryin 2011-09-22
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 sinservice 的回复:]

int a[0] = { 10 };

printf("%d, %d, %d\n", *(int *)&a , *(&a), *a );


如果你能看出这个语句能打印出什么,你就全明白了。
[/Quote]
纠正一个小错误int a[1] = {10};
在我的机器上运行结果为10, 1244996, 10
*(int *)&a 这个是嘛意思??为嘛要用强制类型转换?目的是什么?跟*(&a)有区别吗??
暮雨晨舟 2011-09-21
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 lhcwjy 的回复:]
严格讲,planets[i]的类型是一维数组(绝大多数情况下被编译器转换成指向第一个元素的指针),&planets[i]就是指向一维数组的指针。它们两个的类型是不一样的,但值是一样的(第一个元素的地址也就是整个数组的地址)。一般情况下二者是不能混用的,编译器会报错。但是在这里你恰好用了printf和scanf这两个函数,它们都是可变参数,c语言对可变参数是不进行类型检查的,你在格式字符串中……
[/Quote]
+++
「已注销」 2011-09-21
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 lhcwjy 的回复:]

严格讲,planets[i]的类型是一维数组(绝大多数情况下被编译器转换成指向第一个元素的指针),&planets[i]就是指向一维数组的指针。它们两个的类型是不一样的,但值是一样的(第一个元素的地址也就是整个数组的地址)。一般情况下二者是不能混用的,编译器会报错。但是在这里你恰好用了printf和scanf这两个函数,它们都是可变参数,c语言对可变参数是不进行类型检查的,你在格式字符串……
[/Quote]

这是完整的答案。
白云飘飘飘 2011-09-21
  • 打赏
  • 举报
回复
严格讲,planets[i]的类型是一维数组(绝大多数情况下被编译器转换成指向第一个元素的指针),&planets[i]就是指向一维数组的指针。它们两个的类型是不一样的,但值是一样的(第一个元素的地址也就是整个数组的地址)。一般情况下二者是不能混用的,编译器会报错。但是在这里你恰好用了printf和scanf这两个函数,它们都是可变参数,c语言对可变参数是不进行类型检查的,你在格式字符串中用了"%S",那么编译器就把它们都当成字符串了.
方丈的寺院 2011-09-21
  • 打赏
  • 举报
回复
不好意识,上面的a定义为整形变量
君恪 2011-09-21
  • 打赏
  • 举报
回复
C语言中其实是没有多维数组这个概念的,有的只是数组中嵌套数组。
int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
可以分解为
a[0] 相当于是 {0,1,2,3} 这个数组的数组名

同一楼所说的,数组名和对此数组名取地址,得到的结果是一样的。

方丈的寺院 2011-09-21
  • 打赏
  • 举报
回复
我想问楼主一句:你输出此句printf("%d",a);a已定义,这里你a输出时用了指针?
「已注销」 2011-09-21
  • 打赏
  • 举报
回复
应该是这样

C语言:

int a[1] = { 10 };

printf("%d, %d, %d\n", *(int *)&a , *(&a), *a );

「已注销」 2011-09-21
  • 打赏
  • 举报
回复
int a[0] = { 10 };

printf("%d, %d, %d\n", *(int *)&a , *(&a), *a );


如果你能看出这个语句能打印出什么,你就全明白了。
星羽 2011-09-21
  • 打赏
  • 举报
回复
1 楼不是回答你了吗

数组名就是个地址
对数组名取地址还是这个地址

char planets[9][8]

planets[i] 的类型是 char[8] ,也是个数组


你要改成char* planets[i]就不是数组了

:

const char* planets[9] = {"Mercury","Venus","Earth",
"Mars","Jupiter","Saturn",
"Uranus","Nepturn","Pluto"};
「已注销」 2011-09-21
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hrx1989 的回复:]

引用 1 楼 jixingzhong 的回复:

数组名和对此数组名取地址,得到的结果是一样的。

类似的还有函数名,也有这样的性质。


但是数组名和对数组名取地址得到的指针是不一样的吧???
[/Quote]

实际值是一样的。
hrx1989 2011-09-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jixingzhong 的回复:]

数组名和对此数组名取地址,得到的结果是一样的。

类似的还有函数名,也有这样的性质。
[/Quote]

但是数组名和对数组名取地址得到的指针是不一样的吧???
「已注销」 2011-09-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 jixingzhong 的回复:]

数组名和对此数组名取地址,得到的结果是一样的。

类似的还有函数名,也有这样的性质。
[/Quote]

2楼说对了一半,还有另一半。
「已注销」 2011-09-21
  • 打赏
  • 举报
回复
呵呵,除了我恐怕没有人能够回答你这个问题。

我再等一等。。。。
jixingzhong 2011-09-21
  • 打赏
  • 举报
回复
数组名和对此数组名取地址,得到的结果是一样的。

类似的还有函数名,也有这样的性质。

69,373

社区成员

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

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