-1000原码为什么不存在(-10000为什么没有原码)

c语言的数据不同类型

不同类型的数据在内存中占用的存储单元长度是不同的,例如, Visual C ++为 char (字符型)数据分配1个字节,对int 型(基本整型)数据分配4个字节,存储不同类型数据方法也是不同的。

(一)整型数据

1整型数据的分类

(1)基本整型( int 型)

编译系统分配给 int 型数据2个字节或4个字节(由具体的 C 编译系统自行决定)。如 Turbo C2.0为每一个整型数据分配2个字节(16位),而 Visual C 为每一个整型数据分配4个字节(32位)。

在存储单元中的存储方式是:用整数的补码形式存放。一个正数的补码是此数的二进制形式本身,补全2个字节16位码,如5的二进制形式是101,如果用两个字节存放一个整数,则在存储单元中数据形式是00000000-00000101;如果是一个负数,应先求出负数的补码。负数的补码的方法是:先将此数的绝对值写成二进制形式,然后对其所有二进位按位取反,再加1。

如-5的补码:

5的补全2个字节原码00000000-00000101

5的原码按位取反

11111111-11111010,再加1

-5的补码为11111111-11111011

在存放整数的存储单元中,最左面一位是用来表示数的正负符号的。如果该位为0表示数值为正;如果该位为1,表示数值为负。

如果给整型变量分配2个字节,则存储单元中能存放的最大值为01111111-11111111,第1位为0代表正数,后面15位为全1,此数值是(2^15-1),即十进制数32767。最小值为10000000-00000000,此数是-2^15,即-32768。因此2个字节的一个整型变量的值的范围是-32768~32767。超过此范围,就出现数值的“溢出”,输出的结果显然不正确。

(2)短整型( short int )

类型名为 short int 或 short 。如用 Visual C ++,编译系统分配给 int 数据4个字节,短整型2个字节。存储方式与 int 型相同。一个短整型变量的值的范围是﹣32768~32767。

(3)长整型( long int )

类型名为 long int 或 long 。 Visual C ++对一个 long 型数据分配4个字节(即32位),因此 long int 型变量的值的范围是﹣2^31~(2^31-1),即-2147483648~2147483647。

(4)双长整型( long long int )

类型名为 long long int 或 long long ,一般分配8个字节。 C 标准只要求 long 型数据长度不短于 int 型, short 型不长于 int 型。即 sizeof ( short )≤ sizeof ( int )≤ sizeof(long )≤ sizeof ( long long ),

sizeof 是测量类型或变量长度的运算符。在 Turbo C2.0中, int 型和 short 型数据都是2个字节(16位),而 long 型数据是4个宇节(32位)。通常的做法是:把 long 定为32位,把 short 定为16位,而 int 可以是16位,也可以是32位,由编译系统决定。

在将一个程序从 A 系统移到 B 系统时,需要注意这个区别。例如:在 A 系统,整型数据占4个宇节,程序中将整数50000赋给整型变量 price 是合法的,可行的。但在 B 系统,整型数据占2个字节,将整数50000赋给整型变量 (范围-32768~32767),超过整型数据的范围,出现“溢出”。这时应当把 int 型变量改为 long 型,才能得到正确的结果。

2.整型变量的符号属性

变量值在存储单元中都是以补码形式存储的,存储单元中的第1个二进位制代表符号。整型变量的值的范围包括负数到正数。

整型数据常见的存储空间和值的范围( Visual C ++的安排)

类型 /字节数 /取值范围

int (基本整型)/4字节/

-2147483648~2147483647,即-2^31~(2^31-1)

unsigned int (无符号基本整型)4字节/即0~(2^31-1)

short(短整型)2字节,-32768~32767,即-2^15~(2^15-1)

unsigned short (无符号短整型)2个字节,0~65535,即0~(2^16-1)

long (长整型)4字节,

-2147483648~2147483647,即-2^31~(2^31-1)

unsigned long (无符号长整型)4字节,0~4294967295,即0~(2^32-1)

long long (双长型)8字节,

-9223372036854775808~9223372036854775807,即﹣2^63~(2^63-1)

unsigned long long (无符号双长整型),8字节

0~18446744073709551615,即0~(2^64-1)

在实际应用中,有的数据的范围常常只有正值(如库存量等)。为了允分利用变量的值的范围,可以将变量定义为“无符号”类型。可以在类型符号前面加上修饰符unsigned ,表示指定该变量是“无符号整数”类型。如果加上修饰符 signed ,则是“有符号类型”。因此,在以上4种整型数据的基础上可以扩展为以下8种整型数据:

有符号基本整型[ signed ] int ]

无符号基本整型unsigned int

有符号短整型[ signed ] short [ int ]

无符号短整型unsigned short [ int ]

有符号长整型[ signed ] long [ int ]

无符号长整型unsigned long [ int ]

有符号双长整型[ signed ] long long [ int ]

无符号双长整型unsigned long long [ int ]

方括号表示其中的内容是可选的,既可以有,也可以没有。如果既未指定为 signed 也未指定为 unsigned 的,默认为“有符号类型”。如 signed int a 和 int a 等价。

有符号整型数据存储单元中最高位代表数值的符号(0为正,1为负)。如果指定 unsigned (为无符号)型,存储单元中全部二进位( b )都用作存放数值本身,而没有符号。无符号型变量只能存放不带符号的整数,如123,而不能存放负数。如-123。由于左面最高位不再用来表示符号,而用来表示数值,因此无符号整型变量中可以存放的正数的范围比一般整型变量中正数的范围扩大一倍。如果在程序中定义 a 和 b 两个短整型变量(占2个字节),其中 b 为无符号短整型

short a ;// a 为有符号短整型变量

unsigned short b ;// b 为无符号短整型变量

则变量 a 的数值范围为-32768~32767,而变量 b 的数值范围为0~65535。

(1)只有整型(包括字符型)数据可以加 signed 或 unsigned 修饰符,实型数据不能加。

(2)对无符号整型数据用“% u ”格式输出。% u 表示用无符号十进制数的格式输出。如: unsigned short price =50;//定义 price 为无符号短整型变量。printf ("% u \", price );//指定用无符号十进制数的格式输出

在将一个变量定义为无符号整型后,不应向它赋予一个负值,否则会得到错误的结果。如:unsigned short price=-1;//不能把一个负整数存储在无符号变量中。

printf ("% d \", price ),得到结果为65535。显然与原意不符。

原因是:系统对-1先转换成补码形式,就是全部二进位都是1,然后把它存入变量 price 中。由于 price 是无符号短整型变量,按其左面第一位不代表符号,按“% d ”格式输出,就是65535。

(二)字符型数据

由于字符是按其代码(整数)形式存储的。

1字符与字符代码

字符与字符代码并不是任意写一个字符,程序都能识别的。例如代表圆周率的丌在程序中是不能识别的,只能使用系统的字符集中的字符,目前大多数系统采用 ASCII 字符集各种字符集(包括 ASCII 字符集)的基本集都包括了127个字符。其中包括:

字母:大写英文字母 A ~ Z ,小写英文字母 a ~ Z 。

数字:0~9。

专门符号:29个,包括

!"# &'( ) * 十,一,/ : ; く= >? [ ] _ (丨) ~

空格符:空格、水平制表符、垂直制表符、换行、换页。

不能显示的字符:空( null )字符(以'\0'表示)、警告(以'\ a '表示)、退格(以'\ b' 示)、回车(以 '\r '表示)等。

字符是以整数形式(字符的 ASCII 代码)存放在内存单元中的。如:

小写字母'a ’的 ASCII 代码是十进制数97,二进制形式为1100001。

转义字符’ \n '的 ASCII 代码是十进制数10,二进制形式为0001010。

以上字符的 ASCII 代码最多用7个二进位就可以表示。所有127个字符可以用7个二进位表示,当Ascii代码为127时,为1111111,所以在c语言中,指定用一个字节(8位)存储一个字符(所有系统都不例外)。此时,字节中的第1位置为0。如小写字母’ a 在内存中的存储二进制数为01100001,因为' a ’ASCI1代码是十进制数97。

注意:宇符’1'和整数1是不同的概念。字符'1'只是代表一个形状为‘1'的符号,在需要时按原样输出,在内存中以 ASCII 码形式存储,占用1个字节,而整数1是以整数存储方式(二进制补码方式)存储的,占2个或4个字节。整数运算1十1等于整数2,而字符'1'+'1'并不等于整数2或字符'2'。

2字符变量

字符变量是用类型符 char 定义字符变量。

如:char e ='?';

定义e为字符型变量并使初值为字符’?’。?的 ASCII 代码是63,系统把整数63赋给变量 e 。e是字符变量,实质上是一个字节的整型变量,由于它常用来存放字符,所以称为字符变量。可以把0~127之间的整数赋给一个字符变量。在输出字符变量的值时,可以选择以十进制整数形式输出,或以字符形式输出。如: printf ("% d % c \ n ", e , e),输出结果是63 ?。用“% d ”格式輸出十进制整数63,用“% c ”格式输出字符'?'。

整型变量可以用 signed 和 unsigned 修饰符表示符号属性。字符类型也属于整型,也可以用 signed 和 unsigned 修饰符。

字符型数据的存储空间和值的范围

类 型/字节数/取值范围

signed char (有符号字符型)1字节,-128~127,即-2^8~(2^8-1)

unsigned char (无符号字符型)1字节,0~2^8-1,在使用有符号字符型变量时,允许存储的值为-128~127,但字符的代码不可能为负值,所以在存储字符时实际上只用到0~127这一部分,其第一位均为0。

(三)浮点型数据

浮点型数据是用来表示具有小数点的实数的。

在 C 语言中,实数是以指数形式存放在存储单元中的。一个实数表示为指数可以有不止一种形式,如3.14159可以表示为3.14159×10^0;0.0314159×10^2,314.159X10^(﹣2)等,它们代表同一个值。可以看到:小数点的位置是可以在314159几个数字之间、之前或之后(加0)浮动的,只要在小数点位置浮动的同时就改变指数的值,可以保证它的值不会改变。由于小数点位置可以浮动,所以实数的指数形式称为浮点数。

浮点数类型包括 float (单精度浮点型)、 double (双精度浮点型)、 long double(长双精度浮点型。

浮点数转换为二进制存储

单精度float类型使用32比特存储,其中1位表示符号,8位表示指数,23位表示尾数;双精度double类型使用64比特存储,1位符号位,11位指数位,52位尾数位。

尾数:M是一个二进制小数,因为是二进制,所以科学计数法中这个值范围是:1≤M。对有效数字M和指数E,还有一些特别规定。1≤M<2,也就是说,M可以写成1.xxxxxx的形式,其中xxxxxx表示小数部分。在计算机内部保存 M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01B的时候,只保存01B,等到读取的时候,再把第一位的1加上去。

1将“二进制的浮点数”转换浮点数:

指数为0111 1100B,对应的十进制数124,则二进制指数为124-127=-3,尾数为0.01B,则M=1.01B

浮点数值为

1.01B*[2(-3)]=0.00101B=1/8+1/32=0.15625

2单精度浮点数转换为二进制存储:

十进制数78.375=78+0.375

整数十进制数78=100 1110B

小数十进制数0.375=3/8=1/4+1/8=2^(-2)+ 2^(-3)=0.011B

十进制数78.375=1001110B+0.011B=100 1110.011B=1.001110011B*(2^6)

十进制数78.375在计算机中以二进制存储,

指数为6,则6+127=133=1000 0101B,

尾数为0.001110011B

因此符号为0,指数8位为1000 0101B,尾数23位为00111001100,0000,0000,0000;

单精度浮点数0.5转化二进制数

十进制数0.5=0B+0.1B=0.1B=1.0B*[2^(-1)]小数十进制数0.5=1/2=2^(-1)=0.1B,十进制数0.5在计算机中以二进制存储,其指数为-1,则-1+127=126=0111 1110B,尾数为0.0B,因此符号为0,指数8位为0111 1110B,尾数23位为000,0000,0000,0000,0000,0000;

3双精度浮点数转换为二进制存储:double类型使用64比特存储,1位符号位,11位指数位,52位尾数位。

十进制数78.375=78+0.375,整数十进制数78=1001110B,

小数十进制数

0.375=3/8=1/4+1/8=2^(-2)+2^(-3)=0.011B

十进制数78.375=1001110B+0.011B=100 1110.011B=1.001110011B*(2^6),十进制数78.375在计算机中以二进制存储,指数为6,则6+1023=1029=10000000101B

尾数为0.001110011B,因此符号为0,指数11位为100 0000 0101B,尾数52位为

001110011000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000;

双精度浮点数0.5转化二进制数

十进制数0.5=0+0. 5,整数十进制数0=0B,小数十进制数0.5=1/2=2^(-1)=0.1B,十进制数0.5=0B+0.1B=0.1B=1.0B*[2^(-1)]。十进制数0.5在计算机中以二进制存储,其指数为-1,占11位,则-1+1023=1022=11 1111 1110B,尾数为0.0B,因此符号为0,指数11位为11 1111 1110B,尾数52位为

0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000;

单精度浮点数0.0转化二进制数

浮点数0的尾数

M=1.000,0000,0000,0000,0000,0000B

为了表示近似等于0,就使用

1.000,0000,0000,0000,0000,0000B*[2(-127)]来表示;相当于把远端的1移动过来,所以指数为-127。

浮点数0的指数为-127+127=00000000B,尾数为000,0000,0000,0000,0000,0000B,因此符号为0,指数8位为00000000B。

尾数23位为000,0000,0000,0000,0000,0000B。

双精度浮点数0.0转化二进制数

浮点数0的尾数

M=1.0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000B,

为了表示近似等于0,就使用

1.0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000B *[2(-1023)]来表示;

浮点数0的指数为-1023+1023=000,0000,0000B,

浮点数0的尾数为

0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000B,

因此符号为0,指数11位为000,0000,0000B,

尾数52位为

0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000B。

十进制整数转换为二进制整数:采用“除2取余,逆序排列”法。十进制小数转换成二进制小数:采用“乘2取整,顺序排列”法。

(1) float 型(单精度浮点型)。编译系统为每一个 float 型变量分配4个字节,数值以规范化的二进制数指数形式存放在存储单元中。在存储时,系统将实型数据分成小数部分和指数部分两个部分分别存放。小数部分的小数点前面的数为0。如3.14159在内存中的存放形式:数符+小数部分+指数。在计算机中是用二进制数来表示小数部分以及用2的幂次来表示指数部分的。在4个字节(32位)中,究竟用多少位来表示小数部分,多少位来表示指数部分。有的 C 语言编译系统以24位表示小数部分(包括符号),以8位表示指数部分(包括指数的符号)。由于用二进制形式表示一个实数以及存储单元的长度是有限的,因此不可能得到完全精确的值,只能存储成有限的精确度。小数部分占的位( bit )数愈多,数的有效数字愈多,精度也就愈高。指数部分占的位数愈多,则能表示的数值范围愈大。 float 型数据能得到6位有效数字,数值范围为-3.4X10^(-38)~3.4×10^38。

(2) double 型(双精度浮点型)。为了扩大能表示的数值范围,用8个字节存储一个double 型数据,可以得到15位有效数字,数值范围为-1.7×10^-308~1.7×10^308。为了提高运算精度,在 C 语言中进行浮点数的算术运算时,将 float 型数据都自动转换为 double型,然后进行运算。

(3) long double 型(长双精度)型,不同的编译系统对 long double 型的处理方法不同, Turbo C 对 long double 型分配16个字节。而 Visual C +则对 long double 型和 double 是一样处理,分配8个字节。

(四)确定常量的类型

在 C 语言中,不仅变量有类型,常量也有类型。在程序中出现的常量是要存放在计算机中的存储单元中的。这就必须确定分配给它多少字节,按什么方式存储。例如,程序中有整数12,在 Visual C ++中会分配给它4个字节,按补码方式存储。

确定常量的类型

从常量的表示形式即可以判定其类型。对于字符常量只要看到由单撇号括起来的单个字符或转义字符就可以知道它是字符常量。

对于数值常量按以下规律判断:

整型常量:不带小数点的数值是整型常量,但应注意其有效范围。如在 TurboC 中,系统为整型数据分配2个字节,其表值范围为-32768~32767,如果在程序中出现数值常量23456,系统把它作为 int 型处理,用2个字节存放。如果出现49875,由于超过32767,2个字节放不下,系统会把它作为长整型( long int )处理,分配4个字节。Visual C ++中,在范围-2147483648~2147483647的不带小数点的数都作为 int 型,分配4个字节,在此范围外,而又在 long long 型数的范围内的整数,作为 long long 型处理。在一个整数末尾加大写字母L或小写l,表示它是长整型,例如123L。但在 Visual C ++中由于对 int 和 long int 型数据都分配4个字节,因此没有必要用 long int 型。

浮点型常量

凡以小数形式或指数形式出现的实数均是浮点型常量,在内存中都以指数形式存储。如,10是整型常量,10.0是浮点型常量。C 编译系统把浮点型常量都按双精度处理,分配8个字节。

如果有float a =3.14159;在进行编译时,对 float 变量分配4个字节,但对于浮点型常量3.14159,则按双精度处理,分配8个字节。编译系统会发出“警告”( warning : truncation from ' const double ' to ‘ float )。意为“把一个双精度常量转换为 float 型”,提醒用户注意这种转换可能损失精度。这样的“警告”,一般不会影响程序运行结果的正确性,但会影响程序运行结果的精确度。

可以在常量的末尾加专用字符,强制指定常量的类型。如在3.14159后面加字母 F 或f就表示是 float 型常量,分配4个字节。如果在实型常量后面加大写或小写的 L ,则指定此常量为 long double 型。如:

float a =3.14159f;//把此3.14159按单精度浮点常量处理,编译时不出现“警告”

long double a =1.23L;//把此1.23作为 long double 型处理。


数据二进制存储