1.数据类型
1.1类型分类
整型:
提示1:
字符在内存中存储的是ASCII码值
而ASCII码值是整型,所以字符类型也是整型
提示2:
signed 类型,即有符号数在存储时,有一位符号位
符号位0为正,
符号位1为负
提示3:
int 默认为signed int
想写无符号整型,必须写unsigned int
提示4:
C语言标准并未规定:
char是否是signed char
这取决于编译器
绝大多数编译器为signed char
浮点型:
构造类型(自定义类型)
指针类型:
提示:
void* pv 是无具体类型的指针
空类型:
2.整型在内存中的存储
计算机能处理的是二进制数据
整型和浮点型数据在内存中存储的也都是以二进制的形式进行存储
整数在内存中存储的是二进制序列
整型在二进制中的表现形式有3种:
原、反、补码
2.1原码、反码、补码
正整数:原、反、补码相同
负整数:原、反、补码之间要换算
原、反、补码均有符号位和数值位
原码符号位不变,其余为按位取反为反码
反码加一为补码
最高位(第一位)为符号位:
符号位0为正,
符号位1为负
其余为数值位
2.2存储补码的原因
使用补码可以将符号位和数值位统一处理
加减法统一处理(CPU只有加法器),补码和原码相互转换的计算过程相同,更方便
举例:
1+(-1)
如果用原码计算,其结果为
100000000000000000000000000000010
-2
用补码
结果为:
00000000000000000000000000000000
正确
2.3大小端
相关趣事:
格列夫游记中的剥鸡蛋:
端模式(Endian)起源于《格列佛游记》, 书中根据鸡蛋敲开的方式不同将所有人分为2类,从圆头开始敲的人被归为Big Endian,从尖头开始敲的被归为 Little Endian。小人国的内战就是源于吃鸡蛋是是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开。
大端与小端的存储
- 以字节为单位进行存储 两个十六进制位为1个字节
- 大端字节序存储 int a = 0x11223344 把一个数据低位字节处的数据,存放在高地址处
把一个数据高位字节处的数据,存放在低地址处 - 小端字节序存储 int a = 0x11223344 把一个数据低位字节处的数据,存放在低地址处
###为什么有大端与小端之分
为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8
bit。但是在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处理器还可以由硬件来选择是大端模式还是小端模式。
百度2015年系统工程师笔试题:
请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序。(10分)
//代码1 #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; } //代码2 int check_sys() { union{ int i; char c; }un; un.i = 1; return un.c; }