数据类型1_简介&类型转换
1、c语言中的数据类型
整数类型
基本类型
浮点类型
数组类型
构造类型 结构体类型
c语言数据类型
共用体(联合)
指针类型
空类型(void) 函数执行完不需要结果时
2、学习数据类型三要素
(1)存储数据的宽度
(2)存储数据的格式
(3)作用范围(作用域)
3、整数类型
:char short int long 汇编中
char 8bit 1字节 byte
short 16bit 2字节 word
int 32bit 4字节 dword
long 32bit 4字节 历史遗留问题
4、在反汇编中观察,体验数据宽度的概念
char cTemp = 0xFF; 0xFF
short sTemp = 0xFF; 0x00FF
int nTemp = 0xFF; 0x0000 00FF
char cTemp = 0x12345678; 0x78
short sTemp = 0x12345678; 0x5678
int nTemp = 0x12345678; 0x1234 5678
char == 257 试试 内存中存的1
char == 256
“初始化”: 截断常量值 warning
“初始化”: 从“int”到“char”截断 C4309
整数类型分为有符号(signed)和无符号(unsigned)
类型转换、比较大小和数学运算
- 总结:
- 1.在内存中存储的完全一样
- 2.在做运算的时候需要注意,你把它当什么就是什么,结果完全不同
89: void Test()
90: {
96: char cTemp = 0xFF;
004118BE mov byte ptr [cTemp],0FFh
97: short sTemp = 0xFF;
004118C2 mov eax,0FFh
004118C7 mov word ptr [sTemp],ax
98: int nTemp = 0xFF;
004118CB mov dword ptr [nTemp],0FFh
99: printf("%d\n%d",cTemp,sTemp);
004118D2 movsx eax,word ptr [sTemp]
004118D6 mov esi,esp
004118D8 push eax
004118D9 movsx ecx,byte ptr [cTemp]
004118DD push ecx
004118DE push 41685Ch
004118E3 call dword ptr ds:[41A2BCh]
004118E9 add esp,0Ch
004118EC cmp esi,esp
004118EE call __RTC_CheckEsp (0411181h)
100:
101: char cTemp1 = 0x12345678;
004118F3 mov byte ptr [cTemp1],78h // 注意此处 byte
102: short sTemp1 = 0x12345678;
004118F7 mov eax,5678h
004118FC mov word ptr [sTemp1],ax // 注意此处 ax,word
103: int nTemp1 = 0x12345678;
00411900 mov dword ptr [nTemp1],12345678h
104: printf("%x\n%x",cTemp1,sTemp1); //0x78,0x5678
00411907 movsx eax,word ptr [sTemp1]
0041190B mov esi,esp
0041190D push eax
0041190E movsx ecx,byte ptr [cTemp1]
00411912 push ecx
00411913 push 416864h
00411918 call dword ptr ds:[41A2BCh]
0041191E add esp,0Ch
00411921 cmp esi,esp
00411923 call __RTC_CheckEsp (0411181h)
105:
106: char cTemp2 = 257;
00411928 mov byte ptr [cTemp2],1 // 注意此处 1
107: char cTemp3 = 256;
0041192C mov byte ptr [cTemp3],0 // 注意此处 0
108: unsigned char cTemp21 = 257;
00411930 mov byte ptr [cTemp21],1
109: printf("%d\n%d",cTemp2,cTemp3); // 1,0
00411934 movsx eax,byte ptr [cTemp3]
00411938 mov esi,esp
0041193A push eax
0041193B movsx ecx,byte ptr [cTemp2]
0041193F push ecx
00411940 push 41685Ch
00411945 call dword ptr ds:[41A2BCh]
0041194B add esp,0Ch
0041194E cmp esi,esp
00411950 call __RTC_CheckEsp (0411181h)
110:
111: char cTemp4 = 0xFF;
00411955 mov byte ptr [cTemp4],0FFh
112: unsigned char cuTemp4 = 0xFF;
00411959 mov byte ptr [cuTemp4],0FFh
113: printf("%d\n%d",cTemp4,cuTemp4); // -1,255
0041195D movzx eax,byte ptr [cuTemp4]
00411961 mov esi,esp
00411963 push eax
00411964 movsx ecx,byte ptr [cTemp4]
00411968 push ecx
00411969 push 41685Ch
0041196E call dword ptr ds:[41A2BCh]
00411974 add esp,0Ch
108:
109: }
void Test1()
{
int i = 0xFFFFFFFF;
int j = 0x1;
if (i > j ) 编译结果用的jxx不同
{
printf("i>j,%d\n",i);
}
unsigned int i1 = 0xFFFFFFFF;
unsigned int j1 = 0x1;
if (i1 > j1 )
{
printf("i1>j1%d\n",i1);
}
}
5、类型转换
1. movsx 先符号扩展,再传送。
mov al,0FF; // 如果只看这一行,你说了算
movsx cx,al;
---
0xFF == 1111 1111
符号位是1,所以 1111 1111 1111 1111
cx == 0xFFFF
mov al,0x0F;
movsx cx,al
---
0x0F == 0000 1111
符号位是0,所以 0000 0000 0000 1111
cx == 0x000F
mov al,0x80;
movsx cx,al
---
0x80 == 1000 0000
符号位是1,所以 1111 1111 1000 0000
ecx:11111111--->ecx:1111 FF80.
mov al,0x70;
movsx cx,al
---
0x70 == 0111 0000
符号位是0,所以 0000 0000 0111 0000
ecx:11111111--->ecx:1111 0070.
003E1090 66:B8 690A mov ax,0xA69
003E1094 0FBFC8 movsx ecx,ax
ecx:11111111--->ecx:1111 0A69.
2.movzx 先零扩展,再传送
不管最高位是什么,都是补0,扩展。
003E107E B0 FF mov al,0xFF
003E1080 66:0FB6C8 movzx cx,al
ecx:11111111--->ecx:1111 00FF.
mov al,80;
movzx cx,al
ecx:11111111--->ecx:1111 0080.
003E1084 B0 70 mov al,0x70
003E1086 66:0FB6C8 movzx cx,al
ecx:11111111--->ecx:1111 0070.
// 这边注意数据宽度-和上面的不同
003E1090 66:B8 690A mov ax,0xA69
003E1094 0FB7C8 movzx ecx,ax
ecx:11111111--->ecx:0000 0A69.
1.要拓展容器的大小,如果是有符号的,汇编用movsx,无符号的用movzx.
浮点已经在第一位存符号了,所以不存在无符号的浮点。
2.把一个大的放到小的。(截断低位)
6、Demo
1. 有符号转有符号(movsx)
char cCh = 0xFF;
short sNum = cCh;
int nNu = cCh;
{
00C913EE mov byte ptr [ebp-5],0FFh
00C913F2 movsx ax,byte ptr [ebp-5]
00C913F7 mov word ptr [ebp-14h],ax
00C913FB movsx eax,byte ptr [ebp-5]
00C913FF mov dword ptr [ebp-20h],eax
}
2. 无符号转有符号(movzx)
unsigned char cCh = 0xFF;
short sNum = cCh;
int nNu = cCh;
{
011D13EE mov byte ptr [ebp-5],0FFh
011D13F2 movzx ax,byte ptr [ebp-5]
011D13F7 mov word ptr [ebp-14h],ax
011D13FB movzx eax,byte ptr [ebp-5]
011D13FF mov dword ptr [ebp-20h],eax
}
3. 有符号转无符号(movsx)
char cCh = 0xFF;
unsigned short sNum = cCh;
int nNu = cCh;
{
002513EE mov byte ptr [ebp-5],0FFh
002513F2 movsx ax,byte ptr [ebp-5]
002513F7 mov word ptr [ebp-14h],ax
002513FB movsx eax,byte ptr [ebp-5]
002513FF mov dword ptr [ebp-20h],eax
}
4. 综合
char cCh = 0xFF;
unsigned short sNum = cCh;
int nNu = sNum;
{
00DE13EE mov byte ptr [ebp-5],0FFh
00DE13F2 movsx ax,byte ptr [ebp-5]
00DE13F7 mov word ptr [ebp-14h],ax
00DE13FB movzx eax,word ptr [ebp-14h]
00DE13FF mov dword ptr [ebp-20h],eax
}
5.总结
从小向大扩展的时候,以自身的有无符号为准。
- char 转其他用 movsx;
- unsigned char 转其他用movzx;
6.表达式的特点与数据类型
当表达式中存在不同宽度的变量时,结果将转换为宽度最大的那个。