一个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

1: a = 0x7ffce8387b30, b = 0x559df19e5260, c = 0xf0b5ff

可以看到数组a[4]的首地址为0x7ffce8387b30,指针b分配到的首地址为0x559df19e5260,未初始化的指针c为0xf0b5ff。由于a实在main的函数栈里面,b是在堆上面分得的内存空间,所以二者不处于同一段。

2

2: a[0] = 200, a[1] = 101, a[2] = 102, a[3] = 103

这个很简单,根据代码可以理解。

3

3: a[0] = 200, a[1] = 300, a[2] = 301, a[3] = 302

这个也简单,利用指针c将数组a的元素值进行更改。

4

4: a[0] = 200, a[1] = 400, a[2] = 301, a[3] = 302

利用指针c对数组a的元素进行更改。

5

5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302

这个情况就要复杂些了。
首先需要明白的是在数据在计算机中存储是按小端进行存储的[1]。例如,在计算机中如果存储的十六进制为(按字节):0x12,0x34那么表示的数为0x3412。

[1] 有关大端小端可以参看这篇文章:理解字节序

在我的机器上,一个int类型的数据为4个字节(32bit),一个char类型为1个字节(8bit),所以当前数组a的内容如下:
在这里插入图片描述
在执行完语句c = (int *) ((char *) c + 1);后,指针c指向的位置发生了改变:
在这里插入图片描述
但是此时c仍是指向int型的指针,也就是说c每次改变,则改变4个字节。
接下来的*c = 500;这一句将改变从c开始的4个字节的内容,由于500(10)=00000000 00000000 00000001 11110100(2),所以执行完这句语句后,数组a变为(注意字节序为小端):
在这里插入图片描述
可以看到与输出结果是一致的。

6

6: a = 0x7ffce8387b30, b = 0x7ffce8387b34, c = 0x7ffce8387b31

在执行完

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

后,可以得到此结果。因为char类型指针每次增加一个字节,int类型指针每次增加4个字节。

END.

发布了48 篇原创文章 · 获赞 2 · 访问量 7542

猜你喜欢

转载自blog.csdn.net/wysiwygo/article/details/104112916