说不上是思考,只是想谈谈自己对指针的强制类型转换的理解。之所以写出来,一方面是自己做一个笔记,另一方面也可以和大家探讨探讨,更重要的也是向大家学习。以前总是记不住指针的强制类型转换的格式,归根结底还是自己对这个知识点不够理解。
什么是指针变量
指针变量,本质上是一个变量,只是它是存放地址的变量,指针的类型代表的是它所指向的变量的类型。因此就有了指向整型、字符型、浮点型等其它类型的指针,但实际上所有类型的指针变量存放的都是int型(对于16位编译系统,比如TC,int是2字节,对于32位编译系统,比如VC,GCC,int是4字节)的地址。因此从本质上不同类型的指针变量并没有区别(因为指针变量的类型为int型,因此指针变量只能存放地址。注意和指针指向对象的类型区分开),指针变量所存储的地址为指针所指向的对象的首地址。
#include <stdio.h>
int main(void)
{
int * pint;
char * pchr;
float * pflt;
int a = 2;
char b = 3;
float c = 3.5;
pint = &a;
pchr = &b;
pflt = &c;
printf("pint = 0x%p/n",pint);
printf("pchr = 0x%p/n",pchr);
printf("pflt = 0x%p/n",pflt);
return 0 ;
}
输出结果:
pint = 0x0012FF3C
pchr = 0x0012FF33
pflt = 0x0012FF24
不同类型的指针变量之间的区别
我们都知道不同类型的指针变量指向不同类型的对象,这些指针变量结合指针运算符(*)就等价于指向的对象的值,但我们又知道所有的指针变量的类型都是一样的(都是int型)。到底声明不同类型的指针变量的背后是什么?其实声明不同类型的指针变量既是规定了该变量结合指针运算符时读取内存中的字节数,同样在指针移动和指针的运算时(加、减)在内存中移动的最小字节数。
指针变量强制类型转换转换的背后
首先看个例子
#include <stdio.h>
int main(void)
{
int * pint;
char * pchr;
float * pflt;
int a = 2;
char b = 3;
float c = 3.5;
pint = &a;
pchr = &b;
pflt = &c;
printf("pint = 0x%p/n",pint);
printf("pchr = 0x%p/n",pchr);
printf("pflt = 0x%p/n",pflt);
*(int *)0x0012FF3C = 256; //a的首地址为0x0012FF3C
printf("a = %d/n",a);
pchr = (char *)pint;
printf("*(int *)0x0012FF3C = %d/n",*pchr);
printf("*(int *)0x0012FF3D = %d/n",*(pchr + 1));
printf("*(int *)0x0012FF3E = %d/n",*(pchr + 2));
printf("*(int *)0x0012FF3F = %d/n",*(pchr + 3));
*(int *)0x0012FF3C = 125;
printf("a = %d/n",a);
pchr = (char *)0x0012FF3C;
printf("*(int *)0x0012FF3C = %d/n",*pchr);
printf("*(int *)0x0012FF3D = %d/n",*(pchr + 1));
printf("*(int *)0x0012FF3E = %d/n",*(pchr + 2));
printf("*(int *)0x0012FF3F = %d/n",*(pchr + 3));
return 0 ;
}
输出结果:
pint = 0x0012FF3C
pchr = 0x0012FF33
pflt = 0x0012FF24
a =256
*(int *)0x0012FF3C = 0
*(int *)0x0012FF3D = 1
*(int *)0x0012FF3E = 0
*(int *)0x0012FF3F = 0
a = 125
*(int *)0x0012FF3C = 125
*(int *)0x0012FF3D = 0
*(int *)0x0012FF3E = 0
*(int *)0x0012FF3F = 0
由于 pchr ,pint是不同类型的指针变量,因此在pchr = (char *)pint;语句中需要进行强制类型转换转换。其实在此可以不理解成指针的强制类型转换(因为pint还是指向int型的指针,自身并没有任何改变),暂时可以将pint 理解成存储a变量的首地址的指针变量,这样就和pchr = (char *)0x0012FF3C语句等价,但由于pchr的声明为字符型的指针变量,因此等号的另一端应是一个字符型的地址,所以就将0x0012FF3C声明(强制转化)为字符型的地址。但实际上地址本身就是地址,没有什么字符型、整型等区别的,只是为了方便说明,从理论上说的通,就认为是字符型的吧 (个人是这样理解的)。同样*(int *)0x0012FF3C= 256 可以理解为在内存中用一个int型变量的大小的字节数来存储256这个值,首地址为0x0012FF3C。为了正确存储不同类型的数值,就需要将首地址声明不同类型的地址,来满足存储数据的要求。
以上内容仅是个人理解,不严谨也没经过认真思考,不对之处请大家指正。所涉及的语句,仅仅是个人对该知识点记忆方法。