今天在将一个4字节大小的宏(#define (unsigned long)0x0000FFFF)强制类型转化为8个字节;
然后再左移4个字节(<<32)后;再加上这个宏本身,赋值给一个8字节的变量。产生了一些错误,比较典型,希望大家注意一下。
先贴出正确代码:
#include <stdlib.h>
#include <string.h>
#define NUM (unsigned long)0x0000FFFF
int main(void)
{
unsigned char *Flag = NULL;
int i = 0;
unsigned long long ll = 0;
ll = (((unsigned long long)NUM)<<32)+NUM;
/*打印变量ll的内存,在打印时,可以将变量ll的地址强制转化为字符指针,
然后获取其指针指向的内存(一个字符的内存),获取后指针++,移动一个字节*/
Flag = (unsigned char *)≪
for(i=0 ;i< 8; i++)
{
printf("%x ",*Flag++);
}
return 0;
}
输出结果:
ff ff 0 0 ff ff 0 0 低地址——>高地址
输入分析:因为是运行在inter系统上,是小字节序,输出结果顺序依次是从低地址到高地址,所以其实际的数值为 0x 00 00 FF FF 00 00 FF FF
犯的错误1:忘记“+”号优先级高于"<<"左移优先级,如下代码,
ll = ((unsigned long long)NUM)<<32 + NUM 输出结果:0 0 0 0 0 0 0 0
犯的错误2:对数据类型的强制转换了解不深,导致理解不了产生结果的原因。
事后,对代码进行总结与大家分享:
1、我们如果想要打印某个内存连续的内存值(!!!!!重要)
a 首先我们获取内存的首地址,将其强制类型转化为字符指针
b 然后对指针间接引用,获取指针指向内存的值(此时获取的就是一个字节的内存)
c 对指针加加(++),对指针间接引用,获取指针指向内存的值
如果想一下获取两个字节的内存,将内存首地址强制类型转化为两个字节的指针,N个字节亦如此。
原理:指针的数据类型是告诉编译器,我这个指针指向的内存数据时什么数据类型,你在对我星号(*)间接取值时,就取这个数据类型大小的内存。
2、数据类型的转化
转化规则:位数多的数据类型-->位数少的数据类型 保留低位,舍去高位
位数少的数据类型-->位数多的数据类型 值不变
在类型转换时,只是将内存中读取到的值进行转换,不会对内存的值进行修改,是临时的(很重要)
#include <stdlib.h>
#include <string.h>
int main(void)
{
unsigned short s1 = 0;
unsigned short s2 = 0;
unsigned int i1 = 0;
unsigned int i2 = 0;
s1 = 256*256-1;
i1 = s1;
printf("s1= %x i1= %x \n",s1,i1); /* 输出 s1= ffff i1= ffff*/
i2 = 256*256*256*256-1;
s2 = i2;
printf("i2= %x s2= %x\n",i2,s2); /* 输出 i2= ffffffff s2= ffff 可以明显看出i2
(四个字节)被截成了s2(两个字节)保留低位,舍去高位 */
}
3、基本数据类型取值范围
整型 [signed]int -2147483648~+2147483648
无符号整型unsigned[int] 0~4294967295
短整型 short [int] -32768~32768
无符号短整型unsigned short[int] 0~65535
长整型 Long int -2147483648~+2147483648
无符号长整型unsigned [int] 0~4294967295
字符型[signed] char -128~+127
无符号字符型 unsigned char 0~255
单精度 float 3.4 x 10^(-38)~ 3.4 x 10^(+38)
双精度double 1.7 x 10^(-308)~ 1.7 x 10^(+308)
长双精度 long double 1.7 x 10^(-308)~ 1.7 x 10^(+308)
希望对大家有所帮助。