用指针理解操作

时间:2015-04-08 04:46:51

标签: c pointers

我有一个C编程语言的代码段,如下所示:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
    char *s="Abhas";
    printf(" s = %s \n", s);
    printf(" s + s[1] = %s \n", s+s[1]);
    printf(" s + s[1] - s[3]= %s \n", s+s[1]-s[3]);
    return 0;
}

,输出为: enter image description here

那么,你能帮我澄清一下我们如何得到第二个和最后一个输出线。我是C的新人。

2 个答案:

答案 0 :(得分:4)

printf(" s + s[1] = %s \n", s+s[1]);

相当于:

printf(" s + s[1] = %s \n", s+'b');

相当于:

printf(" s + s[1] = %s \n", s+98);

这将访问它不应该的内存。该程序表现出不确定的行为。

该行:

printf(" s + s[1] - s[3]= %s \n", s+s[1]-s[3]);

相当于:

printf(" s + s[1] - s[3]= %s \n", s+`b'-'a`);

相当于:

printf(" s + s[1] - s[3]= %s \n", s+1);

相当于:

printf(" s + s[1] - s[3]= %s \n", "bhas");

因此输出。

答案 1 :(得分:2)

想想这样的记忆:

   | [0] | [1] | [2] | [3] | [4] | [5] | <- indexes
   +-----+-----+-----+-----+-----+-----+
s: |  A  |  b  |  h  |  a  |  s  | nul | <- characters
   |  65 |  98 | 104 |  97 | 115 |   0 | <- integral values (if ASCII)
   +-----+-----+-----+-----+-----+-----+

以下表达式 - 地址映射显示了正在发生的事情:

s                                -> s       -> &(s[0])
s + s[1]                         -> s + 98  -> &(s[98])
s + s[1] - s[3]  -> s + 98 - 97  -> s + 1   -> &(s[1])

其中,只有第一个和第三个是合法的,因为它们最终在字符串的范围内。第二个是未定义的。

第一个为您提供字符串本身的地址,因此您会看到Abhas

第三个字符为您提供字符串第二个字符的地址,因此您会看到bhas

第二个给你一些不错的字符串,因此会给你任何想要的东西。事实上,作为未定义的行为,它可以为你提供任何东西,没有任何东西,崩溃,格式化你的磁盘,疯狂地通过你的声卡笑,甚至崩溃到一个赤裸裸的奇点,占据我们星球的一大块。


我当然应该提到,除了教你如何使用指针之外,该代码应该从不在野外使用或看到。这是如何编码的经典示例。