【问题标题】:Using printf outside of an array when using pointers to an array使用指向数组的指针时在数组外使用 printf
【发布时间】:2021-04-28 14:27:18
【问题描述】:

我试图更好地理解指针和数组,但偶然发现了一个我无法理解的示例

#include <stdio.h>

int main () {
    char s[] = "bear";
    char(*a)[4] = &s;
    char(*b)[3] = &s;
    char(*c)[2] = &s;
    char(*d)[1] = &s;

    printf("%c%c%c%c\n", a[0][0], b[0][1], c[1][0], d[2][1]);
    system("pause");
    return 0;
}

运行代码我得到“b e a r”

我理解它的方式每一行都说“这是一个 x 长度的字符数组,它的第一个元素是这个 (&s)”,当搜索超出数组范围的内容时,它将解释下一个字符串内存中的数据作为另一个数组(可能会或可能不会给出未定义的行为,具体取决于那里写入的内容)。

所以:

b e a r


b:

b e a

r


c:

b e

a r


d:

b

e

一个

r


行的位置是[x][],列的位置是[][x]

除了d[2][1].之外的所有东西都检查出来

d 只有一列d[x][0],我希望在到达d[2][1] 时会出现分段错误或未定义的行为,就像我运行b[1][2] 时一样,但“r”是打印。这是为什么呢?

【问题讨论】:

    标签: c pointers printf


    【解决方案1】:

    C 允许那些花哨的东西。当您离开d 但您仍在a 内时,您是安全的。

    char(*a)[4] = &s; // a is a pointer to int[4]
    char(*b)[3] = &s; // b is a pointer to int[3]
    char(*c)[2] = &s; // c is a pointer to int[2]
    char(*d)[1] = &s; // c is a pointer to int[1], which is equivalent to int
    

    所有 4 个变量都具有相同的起始地址。但是当你move每个指针时会发生这种情况:

    a[1] == s[4] // When you add 1 to A, it will jump the size of int[4]
    b[1] == s[3] // When you add 1 to B, it will jump the size of int[3]
    c[1] == s[2] // When you add 1 to C, it will jump the size of int[2]
    d[1] == s[1] // When you add 1 to D, it will jump the size of int[1]
    

    您可以检查以下内容: printf("is b[2] == c[3] ? %d\n", b[2] == c[3]);

    比较是这样的:s + 2 * sizeof(int[3]) == s + 3 * sizeof(int[2])? =&gt; s + 2 *sizeof(3 ints) == s + 3 * sizeof(2 ints)? =&gt; YES

    请注意,这样做您已经在s 之外,因此尝试取消引用它可能会给您带来麻烦!我只是在比较地址,而不是在玩存储在其中的值。

    【讨论】:

      【解决方案2】:

      d[2][1] 等同于*(d+2)[1] 等同于*(*(d+2) + 1)

      d[0][0] -> b
      d[1][0] -> e
      d[0][1] -> e
      d[1][1] -> a
      d[2][0] -> a
      d[0][2] -> a
      d[3][0] -> r
      d[2][1] -> r
      d[1][2] -> r
      d[0][3] -> r
      

      【讨论】:

        猜你喜欢
        • 2011-01-27
        • 2015-06-17
        • 1970-01-01
        • 2012-02-07
        • 2023-03-18
        • 2018-01-04
        • 1970-01-01
        • 2021-02-07
        • 2022-08-16
        相关资源
        最近更新 更多