指针变量以及指针变量的类型转换问题

来源:互联网 发布:java生成二维码简单吗 编辑:程序博客网 时间:2024/05/20 20:57
先强调一点,免得以后忘记:通常我们所说的其实是指针变量,而不是指针。指针=变量的地址,指针变量则是存放变量地址的变量。所以要说指针变量,它的首要概念应该是:它本身是一个变量,然后再去理解他的行为与实现。示例:int a=10;void *b;b=&a;printf("%p/n",b); //*b=20; int *c=(int*)b;*c=a;printf("%p",c);上面一段小练习代码,说明了一下空指针变量的基本操作。空指针变量自然也是指针变量,所以你对他进行这样的赋值b=&a;是完全没问题的,并且在打印地址的时候(printf("%p/n",b);),它也能正确打印出a的地址。【 //*b=20; 】这段代码肯定是不正确的,因为b是一个NULL指针,也就是说编译器没办法确定指针变量所指的内存空间的大小,编译器通过识别指针变量的类型(若int *a,则a的类型就是int)来确定指针变量所指的内存空间的大小,从而*b就被解析成了一个int型4个字节的直接地址,对其赋值就ok了。【int *c=(int*)b;】这段代码说明了可以对指针类型进行转换,可以将void*型的转换为int*的,先看下面一段代码:int *a;char *b;char c='a';b=&c;a=(int*)b;printf("%p/n",a);printf("%p",b);这代码说明了从char*转换成int*是没问题的,那么再看下一段:int *e;double *f;double h=2.00f;f=&h;e=(int*)f;printf("%p/t",e);printf("%d/n",*e); printf("%p/t",f);printf("%f/n",*f);//别忘了加*号编译这段代码,安全通过,输出为: 0012FF70 0 0012FF70 2.000000看到了什么f指针变量当然没问题,但是e指针变量输出的值似乎不是你所希望的,或者你觉得这句话【printf("%d/n",*e);】似乎不太对劲,我们可以把它换成【printf("%f/n",*e);】试一下,输出结果: 0012FF70 0.000000 0012FF70 2.000000按照我的理解:很显然,整数和浮点数在内存中的表示方式是不同的,虽然指针都是四个字节组成的变量,它装的都是某个地址,但编译器会根据它的类型来决定取指向地址的几个字节(比如int就是4个字节,char就是一个字节),以及这几个字节所代表的意思(很显然,同样4个字节的int和float的机器表示是不同的),由此就产生了差别。从空指针引出了这么一长串似乎有点长,不过只是为了提醒大家,指针之间可以互相转换,但请参照基本类型之间转换的一些规则,心中有数不是什么都能转的,如此来减少bug量。当然,比较安全的方法应该是根据程序上下文,就是说你知道你在做什么的时候(例:程序只想获得一个指向某个内存单元的指针,以此决定必要的用法),对null指针进行必要的转换,以实现某些特定的功能,这是可取的,但另外的一些,不考虑也罢啦:)
原创粉丝点击