来源:C程序语言设计第四版,谭浩强
计算机组成原理,唐朔飞
计组中,本文最后一道例题,原书中有错。
一、常量,常变量、变量的区别
1、常量:
在程序中其值不能改变的量:
1)如直接使用的数字1,2.1,12e3(12x10^3),'A',“abc”,1.2E3(1.2x10^(-3)),等,e或E之前必须有
数字,且e或E后面必须为整数
2)符号常量:#define PI 3.1416,特点:对符号常量的名字是不分配存储单元,PI只是临时变量,预
编译后就不存在这个符号了,符号所在的位置均变为符号常量的值了
常量就是没有名字的不变量
2、变量:
先定义,后使用:
如int a = 3;
特点:1)有变量名,变量值,有类型,占存储单元
2)变量名是一个存储地址,变量值存在存储地址相应的存储单元中,编译之后一直都存在,
变量值可以被改变
3、 常变量:
C99允许使用常变量:
const int a=3;
特点:1)常变量具有变量的属性,有类型,占存储单元,只是不允许修改值
2)常变量就是有名字的不变量,名字便于在程序中被应用
二、基本数据类型的简述:
基本类型:
整型类型:
基本整型(int)
短整型(short int)
长整型(long int)
双长整型(long long int):C99增加
字符型(char)
布尔型(bool):C99增加
浮点类型:
单精度浮点型(float)
双精度浮点型(double)
复数浮点型(float_complex, double_comple, long long_comple)
1、基本整型(int):
长度:2/4个字节,由C编译系统决定
如:Turbo C2.0,一个int分配2个字节;Visual C++,一个int分配4个字节
存储方式:1)整数的补码进行存放
正数的补码就是该整数的二进制,负数的补码是其绝对值的二进制取反后加一
如:两个字节存储int 5
原码:00000000 00000101
补码:00000000 00000101
两个字节存储int -5
5的补码取反:11111111 11111010
加1:11111111 11111011 (-5的补码)
2)在存放整数的存储单元中,左边的第一位表示符号,0:数值为负;1:数值为正
int 两个字节:
存储单元中最大值:01111111 11111111 2^15-1
存储单元中最小值:10000000 00000000 -2^15
即范围:-32768~32767
int 四个字节:
范围:-2^31~(2^31-1) 既 -2147483648~2147483647
2、短整型(short int):类名:short int 或 short
长度:VC6.0中,2个字节
存储方式:与int相同,-32768~32767
3、长整型(long int):类名:long int 或 int
长度:在VC6.0中,4个字节
储存方式:同int, -2147483648~2147483647
4、双长整型(long long int):类名:long long int 或 long long
长度:一般都是8个字节,C99新增,有的编译器不支持
说明:
1)C标准中没有规定各种类型数据具体长度,均优编译器决定,但是规定了long类型长度不短于int类型长度,
short类型长度不长于int长度。
sizeof(short)<=sizeof(int)<=sizeof(long)<=sizeof(long long)
short int long
Turbo C 2 2 4
VC6.0 2 4 4
2)实际使用中,把long定为32位,short定为16位,int既可以为16位也可以位32位:
如果将A系统移到B系统,要注意溢出问题:
如4字节的int 50000,如果赋值给2字节的int,就会溢出,只能降int修改位long
3)整型变量的符号属性:
5、字符型数据(char):
1)字符与字符代码:
长度:1个字节
存储方式:采用ASCII字符集(一个127个字符)
字母:A~Z,a~z
数字:0~9
专门字符:29个
! " # & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ _ { | } ~
空格符:空格、水平制表符(tab)、垂直制表符、换行、换页(form feed)
不能显示的字符:空(null)字符(以 '\0' 表示)、警告('\a')、退格('\b')、回车('\r')
字符使用ASCII代码存储,1个字节8位、首位为0,直接使用该二进制存储:
如:'a' ASCII中十进制数为97 二进制位01100001
2)字符变量:
char c = '?'
ASCII代码位63,系统直接将整数63赋值给c,c就是字符变量,实质上是一个字节的整型变量,输出:
printf("%d,%c\n",c,c);
结果:63,?
3)符号类型:
6、浮点型数据:
6.1、浮点机中表示(还有一种叫做定点机表示):
1) 浮点数的表现形式:N=S * r^j
2)范围:
3)规格化:将整数部分化为0,小数部分第一位不为0的浮点数形式。
4)例子:
6.2、IEEE 754标准(VC6.0编译器也是使用的这个标准):
现代计算机中,浮点数一般都是采用的IEEE制定的国际标准
标准如下:
说明:符号位S表示整个浮点数的正负,阶码存储的是阶码的真值加一个常数(偏移量:127)
尾数通常都是规划化(非0的最高为总是1)表示,但是在IEEE标准中,有效位如下
格式:1.fff....fff
最终放入尾数时,将整数部分的1忽略,直接用放后面的fff...fff,不足位数,在最后面添0。
例子:求178.126在计算机中的存储方式
原始十进制数:178.126
转化位二进制:10110010.001
二进制浮点表示:1.0110010001*2^111
注意:这里的2^111中,111是二进制数,就是阶码的真值
接下来,使用短实数来表示:
数符:0
偏移的阶码:00000111+01111111=10000110
注意:这里就是阶码的真值加上127,然后作为阶码,加上127原因为了
区分阶码真值的正负数,最终计算机来取这个数时,会主动减127
尾数:01100100010000000000000
注意:这里的尾数应该要忽略二进制浮点数的整数位1,然后不足短实数
中定义的23位,就在结果补0
所以计算机中178.126短实数的二进制存储为:
01000011001100100010000000000000
使用以下程序可以测试:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
float value = 178.126;
unsigned long buff = 0;
memcpy(&buff, &value, 4);//内存拷贝
for (int i = 31; i >= 0; i--)
{
if (((buff >> i) & 1) == 1)
{
printf("1");
}
else
{
printf("0");
}
}
return 0;
}
结果为: