关于一小段有关指针的代码的分析
之前看到这样一段代码
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int a[4] = {150, 250, 350, 450};
int * c = a;
printf("1: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n", a[0], a[1], a[2], a[3]);
c = c + 1;
printf("current c points to %d\n", *c);
c = (int *) ((char *) c + 1);
*c = 500;
printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n", a[0], a[1], a[2], a[3]);
}
经过编译运行,所得结果是
1: a[0] = 150, a[1] = 250, a[2] = 350, a[3] = 450
current c points to 250
2: a[0] = 150, a[1] = 128250, a[2] = 256, a[3] = 450
以下是关于结果的分析
- 首先是关于
c=(int*)((char*)c+1)
执行后,指针c指向位置的问题。
以下由图片说明指针的指向,红色加粗框表示右上角表达式结果指针指向的地址,双线下框表示相应指针的取值范围
- 关于值的问题
将150,250,350,450转为十六进制
分别为0x96,0xFA,0x15E,0x1C2,
由于计算机的小端存储模式1以及int类型占4字节,所以在内存中存储分别为(以下为16进制,省略0x)
96 00 00 00,FA 00 00 00,5E 01 00 00,C2 01 00 00
以下表格对比
十进制 | 十六进制 | 内存存储 |
---|---|---|
150 | 0x96 | 0x96 0x00 0x00 0x00 |
250 | 0xFA | 0xFA 0x00 0x00 0x00 |
350 | 0x15E | 0x5E 0x01 0x00 0x00 |
450 | 0x1C2 | 0xC2 0x01 0x00 0x00 |
500 | 0x1F4 | 0xF4 0x01 0x00 0x00 |
在之前的基础上对数值进行替换,下图为指向*c=500过程分析
十进制 | 十六进制 | 内存存储 |
---|---|---|
150 | 0x96 | 0x96 0x00 0x00 0x00 |
128250 | 0x1F4FA | 0xFA 0xF4 0x01 0x00 |
256 | 0x100 | 0x00 0x01 0x00 0x00 |
450 | 0x1C2 | 0xC2 0x01 0x00 0x00 |
所以运行结束后,a[0]=150,a[1]=128250,a[2]=256,a[3]=450,与实际运行结果相符。
以上。
小端存储模式将数值低位放在内存的低地址中,数值高位放在内存的高地址中 ↩︎