概述
练习题地址:原文指针
代码如下:
#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 = %pn", 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] = %dn",
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] = %dn",
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] = %dn",
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] = %dn",
a[0], a[1], a[2], a[3]);
b = (int *) a + 1;
c = (int *) ((char *) a + 1);
printf("6: a = %p, b = %p, c = %pn", 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.
最后
以上就是开心大雁为你收集整理的一个C语言指针的练习题及其解释的全部内容,希望文章能够帮你解决一个C语言指针的练习题及其解释所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复