搜索
楼主: 超神级
打印 上一主题 下一主题

求助下...为何出错!

[复制链接]
16#
 楼主| 发表于 2014-3-30 22:50:55 | 只看该作者
李掌柜 发表于 2014-3-30 22:32
如果把你的例二改成这样,你看发现了什么问题,和例一比较:

结果是不是很奇怪~~??

#include<stdio.h>
int main()
{
int a,b,c;
int *p = &a;
p[0]=1;
p[1]=2;
p[2]=3;
printf("%d\n%d\n%d\n",a,p,c);
system("pause");
return 0;
}//成功
#include<stdio.h>
int main()
{
int a,b,c;
int *p = &a;
p[0]=1;
p[1]=2;
p[2]=3;
printf("%d\n%d\n%d\n",p[0],b,c);
system("pause");
return 0;
}//成功
#include<stdio.h>
int main()
{
int a,b,c;
int *p = &a;
p[0]=1;
p[1]=2;
p[2]=3;
printf("%d\n%d\n%d\n",p[0],p,c);
system("pause");
return 0;
}//失败
这个是不是感觉很诧异?比你那个跟惊讶吧

点评

这里的例三中的p是一个一维数组才是吧 这个P包含了p[0],p[1],p[2]的所有数值才是呢 你怎么看?  发表于 2014-3-30 23:05
17#
发表于 2014-3-30 22:55:38 | 只看该作者
超神级 发表于 2014-3-30 22:47
这个如果真要讨论的话扯远点.汇编中存在一种字符串拷贝命令MOVSB,把首地址放入一个寄存器,然后把数量放 ...

这和实现关系不大啊,如果你想当教程来教别人,那就要找到语言标准才行,保证语言里都是这么做的,而不是哪家的编译器这么做
我记得很久之前也和你说过,永远不要尝试用汇编去解释C,那是舍本求末,舍近求远的方法

而且,现在例子就摆在眼前,你写的第二段代码,a, b, c三个不是依次分配的

这个结论很难接受吗?
18#
发表于 2014-3-30 22:58:10 | 只看该作者
  1. #include<stdio.h>
  2. int main()
  3. {
  4.   int a,b,c;
  5.   int *p = &a;
  6.   p[0]=1;
  7.   p[1]=2;
  8.   p[2]=3;
  9.   printf("%d\n%d\n%d\n",a,p,c);
  10.   system("pause");
  11.   return 0;
  12. }//成功
复制代码

编译请开-Werror参数
%d对应一个int*……
19#
发表于 2014-3-30 23:00:05 | 只看该作者

当然奇怪啦,
你想想啦
int a,b,c;
三个只有a分了地址,其它二个都木有,
你可以写成这样:
printf("%d\n",&a);
当是不能这样写:
printf("%d\n%d\n%d\n",&a,&b,&c):
b和c,你木有给它值呀~

点评

这儿的*P应该是&a的地址,, *p=&a; 是这样么?  发表于 2014-3-30 23:34
你说的不是最关键的地方  发表于 2014-3-30 23:16
20#
 楼主| 发表于 2014-3-30 23:01:50 | 只看该作者
rosynirvana 发表于 2014-3-30 22:55
这和实现关系不大啊,如果你想当教程来教别人,那就要找到语言标准才行,保证语言里都是这么做的,而不是 ...

不难!我使用了两种不同的编译器测试都是失败了,这个例子我自己思考了是错了.大家测试结果都是一致的!
21#
发表于 2014-3-30 23:03:49 | 只看该作者
李掌柜 发表于 2014-3-30 23:00
当然奇怪啦,
你想想啦
int a,b,c;

b, c要是没分配内存,那要放到哪里去?
22#
发表于 2014-3-30 23:10:43 | 只看该作者
超神级 发表于 2014-3-30 23:01
不难!我使用了两种不同的编译器测试都是失败了,这个例子我自己思考了是错了.大家测试结果都是一致的!

总而言之,不能控制编译器分配内存的行为,所以不能用数个int来模拟int 数组
要模拟“数组”,用的应该是malloc……
23#
 楼主| 发表于 2014-3-30 23:15:16 | 只看该作者
rosynirvana 发表于 2014-3-30 23:10
总而言之,不能控制编译器分配内存的行为,所以不能用数个int来模拟int 数组
要模拟“数组”,用的应该 ...

恩嗯.                    
24#
 楼主| 发表于 2014-3-30 23:15:45 | 只看该作者
李掌柜 发表于 2014-3-30 23:00
当然奇怪啦,
你想想啦
int a,b,c;

#include<stdio.h>
int main()
{
int a,b,c;
printf("a=%d,b=%d,c=%d\n",&a,&b,&c);
int *p = &a;
p[0]=1;
p[1]=2;
p[2]=3;
printf("%d\nb=%d\n%d\n",a,p[1],c);
printf("p[1]=%d地址\n",&p[1]);
printf("p=%d\n",&p);
printf("p[0]=%d",p[0]);
printf("P[2]=%d\n",&p[2]);

system("pause");
return 0;
}//掌柜自己看下

点评

这样报错才怪。  发表于 2014-3-30 23:19
25#
发表于 2014-3-30 23:30:59 | 只看该作者

发现了,其了a 的空间地址没变,b和c的空间地址都变了~~
  1. #include<stdio.h>
  2. int main()
  3. {
  4.         int a,b,c;
  5.         printf("a=%d,b=%d,c=%d\n",&a,&b,&c);
  6.         int *p = &a;
  7.         p[0]=1;
  8.         p[1]=2;
  9.         p[2]=3;
  10.         printf("%d\nb=%d\n%d\n",a,p[1],c);
  11.         printf("p[1]=%d地址\n",&p[1]);
  12.         printf("p=%d\n",&p);
  13.         printf("p[0]=%d\n",&p[0]);
  14.         printf("P[2]=%d\n",&p[2]);

  15.         system("pause");
  16.         return 0;
  17. }
复制代码

1234567.png (2.91 KB, 下载次数: 24)

1234567.png
26#
 楼主| 发表于 2014-3-30 23:38:02 | 只看该作者
李掌柜 发表于 2014-3-30 23:30
发现了,其了a 的空间地址没变,b和c的空间地址都变了~~

嗯,最关键的是它的地址为什么会变。
27#
发表于 2014-3-30 23:44:52 | 只看该作者
超神级 发表于 2014-3-30 23:38
嗯,最关键的是它的地址为什么会变。

总结:
   1. int a,b,c;
    地址可能是随机分的
   2  int p={a,b,c};一维数组
    地址是按顺序分的,
以上总结纯是个人观点,不代表标准
28#
 楼主| 发表于 2014-3-30 23:46:51 | 只看该作者
李掌柜 发表于 2014-3-30 23:44
总结:
   1. int a,b,c;
    地址可能是随机分的

刚才我调试了几次没找到原因。没有证据只是猜测了。
29#
发表于 2014-3-30 23:54:44 | 只看该作者
超神级 发表于 2014-3-30 23:46
刚才我调试了几次没找到原因。没有证据只是猜测了。

呵呵 ~~睡了,明天还要上班呢~~慢慢找吧~~
这二本书应该有答案吧《495个C语言问题》和《C陷阱与缺陷]》
30#
发表于 2014-3-31 00:07:49 | 只看该作者
本帖最后由 rosynirvana 于 2014-3-31 01:31 编辑
超神级 发表于 2014-3-30 23:38
嗯,最关键的是它的地址为什么会变。

你要的东西

ftp://gcc.gnu.org/pub/gcc/summit ... ot%20Assignment.pdf
其中提到,地址分配和变量大小以及引用多少有关(sort the allocated stack slot by size and number of references)

不过这段程序其实只要一个简单的试验就行了
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main()
  4. {
  5.   int a,b,c;
  6.   int *p = &a;
  7.   printf("%p %p %p %p\n", &a, &b, &c, &p);
  8.   p[0]=1;
  9.   p[1]=2;
  10.   p[2]=3;
  11.   printf("%p %p %p\n", &p[0], &p[1], &p[2]);
  12.   system("pause");
  13.   return 0;
  14. }
复制代码


也就是说,内存分布是这样的

  1. FFFFFFF
  2. ……

  3. 0028FF24   p[2]
  4.                      p[1]
  5.                      p[0]  or a
  6.                      b
  7.                      c
  8. 0028FF10  p

  9. ……
  10. 0
复制代码


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

广播台
特别关注
快速回复 返回顶部 返回列表