指针示例代码

代码位置resources/pointers.c

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

void f(void)
{
    int a[4];
    int *b = malloc(16);
    int *c;
    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]);

    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;
}

解读

  1. 以地址的方式打印a,b,c三个变量的值.其中a在栈上,b的值指向堆中的内存,c中的值还未初始化.
  2. 将c指向数组a的起始地址,同时对数组a赋值:100, 101, 102, 103.通过c修改数组第一个元素的值为200.因此打印为: 200, 101, 102, 103.
  3. 通过c修改数组第二个元素为300, 第三个元素为301,第三个元素为302.因此打印为: 200, 300, 301, 302.
  4. c指向数组第二个元素,通过修改为400.因此打印为: 200, 400, 301, 302.
  5. 本代码最复杂的地方来了.c先转换为(char*),然后加1.此时c指向数组第二个元素向上1个字节的位置.此时将c转换为(int*),并赋值500.会同时改变数组第二个元素和第三个元素的值.同时,我们还需要考虑到x86系统的大小端问题,即数据是如何存放的.因此打印为: 200, 128144, 256, 402.
  6. b指向了数组的第二个元素.和上一条类似,c指向了数组起始地址之后1个字节的位置.

运行结果

在我的电脑上运行结果如下:

1: a = 0x7ffeb5035f70, b = 0x10e7010, c = 0x7465675f6f736476
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 = 0x7ffeb5035f70, b = 0x7ffeb5035f74, c = 0x7ffeb5035f71

results matching ""

    No results matching ""