C语言指针类型和类型转换
指针类型
指针是强类型,意思是特定类型的指针变量存放特定类型变量的地址,比如int * 需要一个指向整形的指针来存放整形数据的地址,char* 需要一个指向字符型的指针来存放字符型数据的地址,那为什么说指针是个强类型呢?指针不仅用来表示变量的地址,同时也得使用指针来解引用地址的内容,以此方便修改和使用变量的值。说到这里,我们又得来回顾一下数据类型所占空间的大小(32位机器)
int - 4byte
char - 1byte
float - 4byte
我们用一个实例来说明指针是强类型这个特性,我们知道内存是连续的,我们定义一个变量
int a = 1025;
这个变量用二进制表示为0x10000000001,在内存中的示意可表示如下
字节 | byte3 | byte2 | byte1 | byte0 |
---|---|---|---|---|
二进制值 | 00000000 | 00000000 | 00000100 | 00000001 |
假设地址 | 0x203 | 0x202 | 0x201 | 0x200 |
整形变量的最高位是符号位,也就是正负符号位
类型转换
我们这时去用代码来看一下整形指针、字符型指针的区别
#include <stdio.h>
int main()
{
int a = 1025;
int *p;
p = &a;
printf("size of integer is %d bytes\n",sizeof(int));
printf("Address = %d, value = %d\n",p,*p);
return 0;
}
上面的代码我们知道打印出来的值是a的地址和1025这个值
我们再定义一个字符型指针的变量,再来打印变量的值,将上面的代码修改为
#include <stdio.h>
int main()
{
int a = 1025;
int *p;
char *p0;
p = &a;
printf("size of integer is %d bytes\n",sizeof(int));
printf("Address = %d, value = %d\n",p,*p);
p0 = (char *)p;//这里要做类型转换
printf("size of char is %d bytes\n",sizeof(char));
printf("Address = %d, value = %d\n",p0,*p0);
return 0;
}
打印出来的内容我们看一下
从上面的打印结果来看,p和p0的地址是一样的,那么为什么打印的值却是不同的呢?这里就是数据类型的问题,我们再回到上面的表中,1025 = 0b00000000 00000000 00000100 00000001,整形是以4个字节大小存储的,字符型是以1个字节大小存储的,字符型指针表示整形指针时会将高3位的数据丢失,只留下最低位的字节数据,也就是00000001,所以这里打印出来的值是1。
为了进一步理解这个指针类型,我们看一下p0+1和*(p0+1)的值是多少,代码如下
#include <stdio.h>
int main()
{
int a = 1025;
int *p;
char *p0;
p = &a;
printf("size of integer is %d bytes\n",sizeof(int));
printf("Address = %d, value = %d\n",p,*p);
p0 =(char *) p;
printf("size of char is %d bytes\n",sizeof(char));
printf("Address = %d, Vaule = %d\n",p0,*p0);
printf("Address of p0+1 = %d, Vaule of *(p0+1) = %d\n" ,p0+1,*(p0+1));
return 0;
}
从打印结果来看,p0+1的地址增大一个字节,解引用的值为4,这里的4也就是00000100,上面是强制将p的地址存入p0,它俩的数据类型不同,所存储的内容也有所不同(仅有一个字节数据存入)。提醒我们在使用指针变量时要时刻考虑数据类型,以及是否适合做类型转换。