? 今天在学习指针时,遇到这段代码:
#include <stdio.h>
int main()
{
int a=10;
int* p=&a;
*p=20;
printf("a=%d\n",a);
return 0;
}
运行结果:a=20
本来这段代码是没有问题的,但是我突然产生一个疑问,指针变量只是存放地址,为何还需要区分int* 型、char*型,而且32位系统中sizeof(int*)和sizeof(char*)都是4字节,那么可以用char*型指针指向int型的变量吗?代码如下:
#include <stdio.h>
int main()
{
int a=10;
char* p=&a;
*p=20;
printf("a=%d\n",a);
return 0;
}
运行结果:a=20
欸?感觉没问题啊?我们试着把数值写大一点,代码如下:
#include <stdio.h>
int main()
{
int a=9888;
char* p=&a;
*p=8999;
printf("a=%d\n",a);
return 0;
}
运行结果:a=9767
问题出现了,理论上a应该等于8999,怎么会打印9767呢?9767这个结果怎么来的?
我们知道,第一段代码中:int* p=&a;定义指针变量p为int*型,p的内存空间里存放a的地址,*p指向int型的变量a,而a在内存空间中是占4个字节;
第二段代码中:char* p=&a;定义指针变量p为char*型,p的内存空间里存放a的地址(注意sizeof(char*)是4个字节,可以存放a的地址),但是*p指向的却是int型变量a的低8位,因为char* p定义了*p只能指向char型的变量,而sizeof(char)是1个字节(8比特位)。
看到这部分,你也许觉得很绕,不好理解,但是下面你看到9767是如何得到的,也许你就明白了上面所述一段话的意思。
分析第三段代码:
9888在内存中以二进制存储:0000 0000 0000 0000 0010 0110 1010 0000
8999在内存中以二进制存储:0000 0000 0000 0000 0010 0011 0010 0111
由于char*型指针p指向的是char型,只有8比特位,当*p=8999;编译器只会把8999二进制的低8位赋值给a的低8位,而a原本的高24位依然保留。
因此此时的a在内存中二进制表示为:0000 0000 0000 0000 0010 0110 0010 0111
转化为十进制:9767
这就是打印结果9767的由来。
由此我们知道,指针的类型应该与指向变量的类型保持一致,否则数据一旦稍微大一点,就容易出错,得到我们预料之外的结果。
?
?