2013-03-27 55 views
0

我无法理解这段代码。我不明白为什么sx,sa,sy的值是相同的,这意味着42。我知道它必须对指针做些什么。如果有人可以解释为什么值相同?

#include <stdio.h> 

static int sx; 
static int sa[100]; 
static int sy; 

int main() { 
    int *p; 
    for(p=&sx; p <=&sx+200; p++) 
    { 
     *p = 42; 
    } 
    printf("sx = \t%i\n",sx); 
    printf("sa[0] = \t%i\n",sa[0]); 
    printf("sa[109] = \t%i\n",sa[109]); 
    printf("sy = \t%i\n",sy); 

    getchar(); 
} 
+2

它被称为“未定义的行为”。你很幸运,你没有打开一个黑洞并杀死我们所有人。 – Cornstalks 2013-03-27 04:39:04

+0

为了回应现在删除的评论,为什么它没有给出错误:“未定义的行为”意味着行为是从字面上未定义的。也就是说,*由于所做的事情*会发生任何事情。如果C标准要求给出错误,那么行为将被定义为*(not * un * defined)(它只会被定义为给你一个错误)。未定义的行为完全没有定义当你做某事时会发生什么。 – Cornstalks 2013-03-27 04:46:00

回答

2

你正在写超过变量的范围,所以它是未定义的行为

for(p=&sx; p <=&sx+200; p++) 
{ 
    *p = 42; 
} 

该代码段超出分配给sx的内存并导致未定义的行为。注p是指向sx的指针,而sx只是一个整数而不是数组。该循环迭代并写入超出分配给sx的内存。

未定义行为不一定会导致程序崩溃,它只是意味着程序的输出可以是任何东西。它可能看似工作或不显示或显示一些奇怪的结果,简而言之,任何结果都是可能的。

+0

所以它不应该给出错误而不是给出正确的值? – Mani 2013-03-27 04:40:51

+0

@Mani:*未定义行为*表示行为未定义。它可能会给你一个错误,它可能不会。这完全没有定义。 – Cornstalks 2013-03-27 04:41:29

+0

谢谢你我明白了! – Mani 2013-03-27 04:44:32

5

此代码,您的静态数据的内存布局看起来像这样的假设:

+----+-----------------------------+----+ 
| sx | sa .....     | sy | 
+----+-----------------------------+----+ 

因此,阵列“界”,由sxsy,使使用他们的地址作为边界包括所有sa的元素。在这种情况下,它使用&sx + 200,它可能覆盖sa,然后再多一点(记住,指针算术是缩放的)。

严格来说,这是未定义的行为,你不能依赖于此。但是,这就是为什么它适合你。

0

首先,你的覆盖内存在那里。所以,如果你想用三分球发挥改变这种:

for(p=&sx; p <=&sx+200; p++) 

到:

for(p=&sx; p <=&sy; p++) 

现在,你在做什么有覆盖sxsy之间的每个存储位置值42。并且发生sx,sysa的每个元素都在那些存储器地址中。

而且,BTW代码对内存布置做出了假设,这在每台计算机中可能都不是这样。

+0

仅仅执行'&sx <=&sy'也是未定义的行为。惊喜。 – 2013-03-27 05:42:36

相关问题