⛳前言+目录:
大小端字节序 和整型提升 是C语言中重要的知识点,其中的很多细节对初学C语言的小伙伴来说不是很友好,因此我总结了 大小端字节序 和 整型提升 的易错点,给你全面的介绍,一举掌握大小端字节序和整型提升⛵🚤🚢
⛳⛳大小端字节序:
概念:
--->高位 --->低位
int a = 0x11223344;
620
---> 一个字节
字节序:以字节为单位,讨论它的排序
大端字节序:指数据的高位保存在低地址处,数据的低位保存在高地址处
(低地址)11 22 33 44(高地址)
小端字节序:指数据的高位保存在高地址处,数据的低位保存在低地址处
(低地址)44 33 22 11(高地址)
为什么有大端和小端:
为什么会有大小端模式之分呢?
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。
但是在C语言中除了8 bit的char之外,还有16 bit的short型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
例如:一个 16bit 的 short 型 x ,在内存中的地址为 0x0010 , x 的值为 0x1122 ,那么 0x11 为高字节, 0x22 为低字节。对于大端模式,就将 0x11 放在低地址中,即 0x0010 中,0x22 放在高地址中,即 0x0011 中。小端模式,刚好相反。我们常用的 X86 结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。
记住这个代码(判断当前机器的字节序):
#include <stdio.h> int check_sys() { int i = 1; return *((char*)&i); } int main() { int ret = check_sys(); if (ret == 1) printf("小端\n"); else printf("大端\n"); return 0; }
⛳⛳整型提升:边做边学,提高更快
🌵练习1:
结果是:-1、 -1、255
① char a = -1;
-1:
10000000 00000000 00000000 00000001(原码)
11111111 11111111 11111111 11111110 (反码)
11111111 11111111 11111111 11111111 (补码)
因为是char类型,则-1(补码)要发生截断
存的是:11111111
②signed char b = -1;
-1:
11111111 11111111 11111111 11111111(补码)
因为是char类型,则-1(补码)要发生截断
存的是:11111111
③unsigned char c = -1;
-1:
11111111 11111111 11111111 11111111(补码)
因为是char类型,则-1(补码)要发生截断
存的是:11111111
④printf ("a=%d,b=%d,c=%d",a,b,c);
%d 打印的是有符号整型,本题a、b、c都是char类型,因此要发生整型提升👇👇👇
a 进行整型提升:
a 是char类型,是有符号位的,则截断后的11111111,在高位要补上1
11111111 11111111 11111111 11111111(补码)
因为要 printf ,所以求出它的原码
10000000 00000000 00000000 00000001(原码)
b 进行整型提升:
b 是signed char类型,是有符号位的,则截断后的11111111,在高位要补上1
11111111 11111111 11111111 11111111(补码)
因为要 printf ,所以求出它的原码
10000000 00000000 00000000 00000001(原码)
c 进行整型提升:
c 是unsigned char类型,是无符号位的,则截断后的11111111,在高位要补上0
00000000 00000000 00000000 11111111(补码)
因为要 printf ,所以求出它的原码
00000000 00000000 00000000 11111111(原码)
🌵练习2:
结果是:4294967168、4294967168
① char a = -128;
-128:
10000000 00000000 00000000 10000000(原码)
11111111 11111111 11111111 01111111(反码)
11111111 11111111 11111111 10000000(补码)
因为是char类型,则-128(补码)要发生截断
存的是:10000000
②char a = 128;
128:
00000000 00000000 00000000 10000000(原码)
00000000 00000000 00000000 10000000(反码)
00000000 00000000 00000000 10000000(补码)
因为是char类型,则128(补码)要发生截断
存的是:10000000
③printf ("%u,%u",a,b);
%u 打印的是无符号整型,本题a、b都是char类型,因此要发生整型提升👇👇👇
a 进行整型提升:
a 是char类型,是有符号位的,则截断后的10000000,在高位要补上1
11111111 11111111 11111111 10000000(补码)
因为要 printf ,所以求出它的原码
11111111 11111111 11111111 10000000(原码)
b 进行整型提升:
b 是char类型,是有符号位的,则截断后的10000000,在高位要补上1
11111111 11111111 11111111 10000000(补码)
因为要 printf ,所以求出它的原码
11111111 11111111 11111111 10000000(原码)
🌵练习3:
结果是:-10
① int i = -20;
-20:
10000000 00000000 00000000 00010100(原码)
11111111 11111111 11111111 11101011(反码)
11111111 11111111 11111111 11101100(补码)
因为是 int 类型,则-20(补码)
存的是:11111111111111111111111111101100
②unsigned int j = 10;
10:
00000000000000000000000000001010(补码)
因为是unsigned int 类型,则10(补码)
存的是:00000000000000000000000000001010
③printf ("%d\n", i+j);
%d 打印的是有符号整型,本题 i、j 都是 int 类型,不用整型提升
⛳结语:
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹