int和char指针如何影响我的打印输出?

时间:2013-02-01 15:31:39

标签: c pointers

所以这里是代码,直到第4次打印我很容易跟着它,但是在第5次打印时,我不明白

为什么"5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302 "

我在代码中注释了一些我不理解的内容。我期待着你的回复。

"#include <stdio.h>
#include <stdlib.h>

void
f(void)
{
    int a[4];
    int *b = malloc(16);
    int *c = 0;
    int i;

    printf("1: a = %p, b = %p, c = %p\n", a, b, c);

    c = a;
    for (i = 0; i < 4; i++)
    a[i] = 100 + i;

    c[0] = 200;
    printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
       a[0], a[1], a[2], a[3]);

    c[1] = 300;
    *(c + 2) = 301;

    3[c] = 302;
    printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
       a[0], a[1], a[2], a[3]);

    c = c + 1;
    *c = 400;

    printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
       a[0], a[1], a[2], a[3]);

    //I DONT UNDERSTAND WHAT THIS LINE BELOW DOES
    c = (int *) ((char *) c + 1);

    *c = 500;
    printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
       a[0], a[1], a[2], a[3]);

    b = (int *) a + 1;
    c = (int *) ((char *) a + 1);
    printf("6: a = %p, b = %p, c = %p\n", a, b, c);
}

int
main(int ac, char **av)
{
    f();
    return 0;
}



output:
1: a = 0x7fff65fdcb90, b = 0x1065007e0, c = 0x0
2: a[0] = 200, a[1] = 101, a[2] = 102, a[3] = 103
3: a[0] = 200, a[1] = 300, a[2] = 301, a[3] = 302
4: a[0] = 200, a[1] = 400, a[2] = 301, a[3] = 302
5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302
6: a = 0x7fff65fdcb90, b = 0x7fff65fdcb94, c = 0x7fff65fdcb91

2 个答案:

答案 0 :(得分:8)

让我们从基础开始。

c是指向int s。

数组的指针

这是a

[00000000][00000000][00000000][00000000]

每两个数字都是一个字节,我们假设sizeof(int)在我们的例子中是4,所以a中的每个元素都有4个字节,或8个数字。

现在,c是指向a中第一个元素的指针。

让我们来看看有问题的表达式:

c = (int *) ((char *) c + 1);

显然,c在这里有所改变,但究竟发生了什么:

  1. cint*投射到char*
  2. 演员表的结果递增,导致sizeof(char)被添加到c。由于sizeof(char)1c会增加1并指向a中元素的第二个字节
  3. 结果会转回int*,并重新分配给c。实际上不需要第二次演员。
  4. 因此,忽略所有其他代码,我们从这开始:

    a : [00000000][00000000]...
         ^
      c -|
    

    转到此:

    a : [00000000][00000000]...
           ^
      c ---|
    

    正如Daniel在下面指出的那样,如果c未正确对齐int*类型的指针,则会得到未定义的行为,这应该避免。

答案 1 :(得分:3)

c是一个指向int的指针,因此通常c+1指向内存中sizeof(int)的地址 - 通常是32位系统上的4个字节。< / p>

但是你将c转换为char* - 即指向char的指针。现在,char只有1个字节长,因此(char *)c + 1指的是比c更远的内存位置 1个字节; 位于<{1}} int {/ 1}}中间的

然后,您将结果转换回c并将500写入其中。所以你正在做的(可能)在int*的最后3个字节和a[1]的第1个字节上写入500字节的4字节表示。究竟会产生什么影响取决于系统的字节顺序,但这基本上是正在发生的事情。