普通变量类型
如int类型
在程序中,定义 int a = 5;
这个变量a就会被赋予内存中的两种东西,一是一个内存地址,二是这个内存地址所指向的一段内存空间。以及定义了变量a中的数据的解析方法。
变量的内存地址,是指变量被赋予的内存空间的最小地址。例如定义了int a = 5;a的内存空间会涵盖32位的大小,一个地址指向一个字节大小,所以a所指向的内存空间里会有4个地址。而a的地址是这四个地址中的最小的那个。如下图。
变量被赋予的内存空间的大小,由变量类型决定,如果是char型,则赋予8位一字节大小的内存空间;short类型则赋予16位两字节大小的内存空间;int则赋予32字节四字节大小的内存空间。
在内存中存储数据,是以二进制的形式存放的。所以在程序中出现的十进制数据和十六进制数据,都是要通过编译器进行转换,将其变为二进制数据后才能使用的。所以不同的变量类型之间的数据转换方式不同。
像char,short,int等整形变量类型,它们的数据解析方式是相同的。但是和float,double是不一样的。但是char,short,int等整形变量在解析时受到一个数据大小的限制,像char类型,只能正确解析-128~127的数据;超出这个大小后,数据就出错了。同理short类型。整形变量类型的大小:char<short<int。
float和double都有自己各自的数据解析方法。
所以如果定义了int a = 5;但是用printf以%f的格式输出,结果肯定是乱码。
指针变量类型
如int *类型
在程序中,定义 int *p;
指针的实质也是一个变量。当定义了int *p;后,指针变量p也会被赋予两样东西。一是一个内存地址,二是这个内存地址所指向的一段内存空间。以及定义了该指针变量p中能存放的是什么类型的变量的地址。以及在解指针时用什么解析方法去解析指针变量所指向的变量中的数据。
这里变量的内存地址的解释和普通变量的一样。
指针变量在内存中被赋予的内存空间是固定的。不论是什么类型的指针变量,在内存中都是被赋予32位的内存大小。
解析数据的问题上,指针变量要复杂一些。一个指针会涉及到两个变量:**一个是指针变量本身;一个是指针变量所指向的那个变量。**对于指针变量本身的内存空间内的数据的解析方法,所有指针类型都是相同的。都是将其解析为地址。对于指针变量所指向的那个变量(也就是解指针的时候)的解析方式,则是不同的。如果是 int *,那么就是以int类型去解析;如果是float *,那么就是以float类型去解析。
例如:
int a = 5;
int *p1 = &a;
float *p2 = (float *)&a;
printf("a的地址 = %p\n",&a);
printf("p1指向的地址 = %p\n",p1);
printf("p2指向的地址 = %p\n",p2);
最后的执行结果,三个的结果是一样的。
虽然p1和p2是不同的指针变量类型。但是由于对于不同指针变量,其解析指针变量内部的数据时,用的是同一种解析方法,所以得到的数据,都是相同的。
int a = 5;
int *p1 = &a;
float *p2 = (float*) &a;
printf("a的地址 = %p\n",&a);
printf("p1指向的地址 = %p\n",p1);
printf("p2指向的地址 = %p\n",p2);
printf("a = %d\n",a);
printf("*p1 = %d\n",*p1);
printf("*p2 = %f\n",*p2);
解指针。得到的结果
*p2的结果已经明显有问题了,这就是因为p2的指针类型是float *的原因。由于p2的指针类型是float *,所以在解指针时,编译器是以float类型去解析
p2指向的变量中的数据的。而p2指向的变量是一个int型的变量,所以在解析的时候就出现问题了。