指针和指针强制转换( 回忆版 )-------让初学者理解
什么是指针:
首先我们需要知道指针是什么,说白了,就是地址( 一般我不讲指针,因为一个新的名词突然出现太难以理解 ),那么为什么又分成int*, float*…,之类呢?
我们可以测试,在windows 32位下,sizeof( int* )和sizeof( float* )都是4B,也就是指针仅仅是地址而已,它指向的是一个数据(可能是一系列的数据元素组成的结构体,也可能仅仅是一个数据元素)。
内存单元1
内存单元2
内存单元3
内存单元4
……
不同的数据占用的内存单元数十不一样的!也就是int*指向的数据和float*指向的数据占用的内存单元不一样,那么我们通过指针来取数据的时候,知道指针类型就知道了数据类型,继而可以知道读取数据的时候读几个单元!这就是指针!
同时区分类型还有一个好处就是:当指针在移动的时候我们通过类型就知道一步移动要涉及几个内存单元!而不需要额外的增加信息来说明!( 这也就是为什么void*指针无法进行加减运算!因为不知道类型是无法进行的! )。
下面看一个程序:
#include <stdio.h>
short g_i;
short *p_i;
int main()
{
p_i = &g_i;
*p_i = 12;
return 0;
}
反汇编后:
在windows中dword是双字,32位下为4B,第一句p_i = &g_i;汇编码中和第二句中的第二句汇编是dword,也就是说明地址是dword的( 4B ),而最后一句汇编码是word,这是由于short型决定数据的大小是2B( 一个字大小 ),那么大家就会知道,如果将short改成char,那么word就会变成byte,当然是对的!所以指针其实就是这么easy!
指针强转:
看简单的代码:
#include <stdio.h>
int * g_i;
short *p_i;
int main()
{
g_i = p_i; //当然此句报错
g_i = ( int* )p_i;
return 0;
}
我们知道指针变量直接赋值会编译报错,但是强转后就是ok的,那么强转到底做了什么呢?
调试代码:
int i;
int * pi;
short * ps;
char * pc;
int main()
{
pi = &i;
ps = ( short* )&i;
pc = ( char * )&i;
*pi = 0x1234;
*ps = 0x1234;
*pc = 0x12;
return 0;
}
反汇编后:
并没有额外的语句告诉编译器,所以强转仅仅是警告编译器我需要这么做而已!
同时我们可以看到下面的赋值语句中分别是 dword、word、byte,也就是说明编译器已经知道要这么做了,所以就将类型改过了!
那么我们知道对于int型的数据,如果转为short,那么必然会有数据丢失( 因为数据单元不够,那么就会截断部分! ),但是这样不会造成越界访问!!!所以,安全的强转是大类型(数据占用单元多)转为小类型(数据占用单元少)( 所谓安全就是宁愿数据缺失也不能越界! )
所以上面两句强转: ps = ( short* )&i;
pc = ( char * )&i;
都是安全的!!!
补充:综合编程 , 其他综合 ,