搜索
查看: 6576|回复: 71
打印 上一主题 下一主题

求助下...为何出错!

[复制链接]
跳转到指定楼层
楼主
发表于 2014-3-30 21:06:00 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 超神级 于 2014-3-30 23:20 编辑

//以下为错误教程!下面帖子为讨论...看着玩吧
本文的目的更透彻了解数据结构!基础篇.
先来段程序运行下;
#include<stdio.h>
int main()
{
int a,b,c;
printf("a=%d\nb=%d\nc=%d",&a,&b,&c);
    printf("看到了吗!a+4=b,b+4=c的地址!\n");
system("pause");
return 0;
}
why!因为在程序编译的int a,b,c;会向系统请求一块大小为12个字节大小的内存空间所以内存空间是连续的(理论是这样的)!
(a,b,c是在编码、编译阶段的一个符号,在最终的可执行代码中是不存在的,所以不占空间)。
上面东西和数据结构有什么关系先别急嘛!请看下文分解!
我们要使用上面的东西来模拟下简单数组没有结构那些乱七八糟的东西只有一些大家都熟悉的东西.

#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",a,b,c);
system("pause");
return 0;
}
/*
按照理论来讲应该没什么刚才我测试上面代码竟然报错也没调试出
原因!本来想写个教程的郁闷!、、后面还有半段内容等找出上面代码错误原因在继续写.
希望大神帮忙给个解答!上面代码为何错误.
*/


来自 5#
发表于 2014-3-30 22:06:30 | 只看该作者
还有我记得和你说过一次
指针有自己的占位符%p,不要用%d输出地址
推荐
发表于 2014-3-30 21:22:32 | 只看该作者
本帖最后由 rosynirvana 于 2014-3-30 21:27 编辑

printf("%d\n%d\n",a,b,c);
这里
我改了这句然后能编译

标准可没有承诺过把a,b,c依次分配内存
不知道你在哪里看到的?

下面那段代码,把printf那句修正后,我这里输出是
1
3
2

所以说gcc的实现也不是把a,b,c依次分配的
板凳
发表于 2014-3-30 21:26:53 | 只看该作者
如果是
struct foo{
int a; int b; int c}

印象中标准承诺a会在b前面,b会在c前面,但是没有承诺连续(一般实现是连续的)
所以这类东西如果不大清楚一定要去查语言标准

点评

恩恩  发表于 2014-3-30 23:50
地板
发表于 2014-3-30 22:01:30 | 只看该作者
你的第一个例子的地址,我电脑上是这样的:
和你说的空间大小不一样,,,

123.png (2.98 KB, 下载次数: 31)

123.png
6#
 楼主| 发表于 2014-3-30 22:15:26 | 只看该作者
李掌柜 发表于 2014-3-30 22:01
你的第一个例子的地址,我电脑上是这样的:
和你说的空间大小不一样,,,

好吧!你反着算..c+4=b;b+4=a

点评

我就觉得有点怪意,,你的代码我可没修改过~~  发表于 2014-3-30 22:21
我就觉得有点怪意,,你的代码我可没修改过~~  发表于 2014-3-30 22:21
7#
 楼主| 发表于 2014-3-30 22:15:50 | 只看该作者
rosynirvana 发表于 2014-3-30 22:06
还有我记得和你说过一次
指针有自己的占位符%p,不要用%d输出地址

恩恩!10进制容易观察!
8#
发表于 2014-3-30 22:25:14 | 只看该作者
超神级 发表于 2014-3-30 22:15
恩恩!10进制容易观察!

抓重点,你从哪里看到的
int a, b, c;
那么a, b, c就会被依次连续分配内存?
9#
发表于 2014-3-30 22:32:58 | 只看该作者
本帖最后由 李掌柜 于 2014-3-30 22:36 编辑
超神级 发表于 2014-3-30 22:15
恩恩!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("a=%d\nb=%d\nc=%d\n",a,b,c);
  10.         printf("a=%d\nb=%d\nc=%d\n",p[0],p[1],p[2]);
  11.         printf("a=%d\nb=%d\nc=%d\n",&p[0],&p[1],&p[2]);

  12.         system("pause");
  13.         return 0;
  14. }
复制代码

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

12345.png (1.98 KB, 下载次数: 21)

12345.png
10#
 楼主| 发表于 2014-3-30 22:35:16 | 只看该作者
本帖最后由 超神级 于 2014-3-30 22:36 编辑
rosynirvana 发表于 2014-3-30 22:25
抓重点,你从哪里看到的
int a, b, c;
那么a, b, c就会被依次连续分配内存?

复杂数据类型!数组是由其他类型派生出来的.我们当然可以反向模拟
11#
发表于 2014-3-30 22:36:36 | 只看该作者
超神级 发表于 2014-3-30 22:35
复杂数据类型!数组是由其他类型派生出来的.

你从哪里看到的?
数组是一片连续的内存,但是a, b, c 3个变量不是啊(标准中没有要求编译器这么做)

点评

我忘了!等下查下  发表于 2014-3-30 22:40
12#
 楼主| 发表于 2014-3-30 22:40:10 | 只看该作者
rosynirvana 发表于 2014-3-30 22:36
你从哪里看到的?
数组是一片连续的内存,但是a, b, c 3个变量不是啊(标准中没有要求编译器这么做)

地址应该是连续的!假定数组是由int派生出来的,数组地址连续,那么int同样可以模拟数组啊!
13#
 楼主| 发表于 2014-3-30 22:41:29 | 只看该作者
李掌柜 发表于 2014-3-30 22:32
如果把你的例二改成这样,你看发现了什么问题,和例一比较:

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

掌柜给你看个让你更惊讶的3段代码
14#
发表于 2014-3-30 22:41:33 | 只看该作者
超神级 发表于 2014-3-30 22:40
地址应该是连续的!假定数组是由int派生出来的,数组地址连续,那么int同样可以模拟数组啊!

int arr[3];
3个连续的int, ISO C标准要求这么做

int a, b, c;
3个连续的int ? 谁说的?不要想当然啊
15#
 楼主| 发表于 2014-3-30 22:47:15 | 只看该作者
rosynirvana 发表于 2014-3-30 22:41
int arr[3];
3个连续的int, ISO C标准要求这么做

这个如果真要讨论的话扯远点.汇编中存在一种字符串拷贝命令MOVSB,把首地址放入一个寄存器,然后把数量放入另一个寄存器,随后是目的地址寄存器,汇编语言中的字符串拷贝命令和C中的数组命令是类似的,就是要求地址连续!反汇编看下int 的实现我想应该一致。

点评

未测试  发表于 2014-3-30 22:47
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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