【C语言笔记】——3.数据类型(2)

一、数据

数据是指对客观事件进行记录并可以鉴别的符号,是信息的表现形式和载体。据所指代的并不仅是狭义上的数字,还可以包括符号、文字、语音、图形和视频等。
简单来说就是有用的信息

那么,数据如何存储在内存中?

1. 确认数据的类型  10 3.14 'a' '1' "10" "100" 'a'
2. 根据数据的类型在c语言中确认分配的数据类型 int char float double
3. 确认分配的空间是否满足数据的存放 char:1字节 short 2字节 int 4字节

二、数据类型的尺寸

整型数据尺寸是指某种整型数据所占用内存空间的大小

C语言标准并未规定整型数据的具体大小,只规定了相互之间的 “ 相对大小 ” ,比如:

  • short 不可比 int 长
  • long 不可比 int 短
  • long 型数据长度等于系统字长

系统字长:CPU 一次处理的数据长度,称为字长。比如32位系统、64位系统。

典型尺寸:

  • char 占用1个字节
  • short 占用2个字节
  • int 在16位系统中占用2个字节,在32位和64位系统中一般都占用4个字节
  • long 的尺寸等于系统字长
  • long long 在32位系统中一般占用4个字节,在64位系统中一般占用8个字节

 存在问题:

同样的代码,放在不同的系统中,可能会由于数据尺寸发生变化而无法正常运行。

因此,系统标准整型数据类型,是不可移植的,这个问题在底层代码中尤为突出。

三、数据的进制表示 

 1. 进制

  • 十进制:
    • 由十个数码来表示的数。分别是:0、1、2、3、4、5、6、7、8、9
    • 遵循的原则是:逢十进一
  • 二进制:
    • 由两个数码来表示的数。分别是:0、1
    • 遵循的原则是:逢二进一
  • 八进制:
    • 由八个数码来表示的数。分别是:0、1、2、3、4、5、6、7
    • 遵循的原则是:逢八进一
  • 十六进制:
    • 由十六个数码来表示的数。分别是:0、1、2、3、4、5、6、7、8、9、A、B、C、 D、E、F
    • 遵循的原则是:逢十六进一
    • 表示方法:一个数占四个比特位

补充:

  • 字节(Byte):
    • 计算机中数据储存的单位,也是数据读取的最小单位(按字寻址的系统除外)
    • 位(bit):也叫作“比特”,计算机中数据储存的最小单位,因为在计算机中是以二进制的形式数据储存,所以每个位以“0”或“1”表示
    • 字节与位的关系:1Byte=8bit
    • 1KB=1024B(2^10)、1MB=1024KB、1GB=1024MB、1TB=1024GB

2. 进制转换方法

  • 十进制转二进制

        短除法

  • 十六进制转二进制:十六进制中的任意字节码都能用四个二进制字节码表示

  • 八进制转二进制:八进制中的任意字节码都能用三位个二进制字节码表示

  • 二进制转十进制:2的次方形式

011100 -> 0*2^5+1*2^4+1*2^3+1*2^2+0*2^1+0*2^0 =16+8+4=28

  • 二进制转十六进制:

00101100 -> 2C

11 0010 1010 ->0011 0010 1010->32A

  • 二进制转八进制:

001 101 011 -> 153

四、类型转换 

不一致但相互兼容的数据类型,在同一表达式中将会发生类型转换

转换模式:

  • 隐式转换:系统按照隐式规则自动进行的转换

  • 强制转换:用户显式自定义进行的转换

1. 隐式转换

隐式规则:从小类型向大类型转换,目的是保证不丢失表达式中数据的精度

转换按数据长度增加的方向进行,以保证数值不失真,或者精度不降低。例如,int 和 long 参与运算时,先把 int 类型的数据转成 long 类型后再进行运算

char  a = 'a';
int   b = 12;
float c = 3.14;
float x = a + b - c; // 在该表达式中将发生隐式转换,所有操作数被提升为float
  • 字符必须先转换为整数(C语言规定字符类型数据和整型数据之间可以通用) 。
  • short型转换为int型(同属于整型)
  • float型数据在运算时一律转换为双精度(double)型,以提高运算精度(同属于实型)
  • 若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型
  • 若两种类型的字节数不同,转换成字节数高的类型

2. 强制转换

用户强行将某类型的数据转换为另一种类型,此过程可能丢失精度

#include<stdio.h>

int main()
{
    int sum = 103;  //总数
    int count = 7;  //数目
    double average;  //平均数
    average = (double) sum / count;
    printf("Average is %lf!\n", average);
    return 0;
}

运行结果:

sum 和 count 都是 int 类型,如果不进行干预,那么sum / count的运算结果也是 int 类型,小数部分将被丢弃;虽然是 average 是 double 类型,可以接收小数部分,但是心有余力不足,小数部分提前就被“阉割”了,它只能接收到整数部分,这就导致除法运算的结果严重失真。既然 average 是 double 类型,为何不充分利用,尽量提高运算结果的精度呢?为了达到这个目标,我们只要将 sum 或者 count 其中之一转换为 double 类型即可。上面的代码中,我们将 sum 强制转换为 double 类型,这样sum / count的结果也将变成 double 类型,就可以保留小数部分了,average 接收到的值也会更加精确。

不管是隐式转换,还是强制转换,变换的都是操作数在运算过程中的类型,是临时的,操作数本身的类型不会改变,也无法改变。

 五、码制

  • 正数:原反补一致,均是原码本身,例如10
    • 原码:0 000 1010
    • 反码:0 000 1010
    • 补码:0 000 1010
  • 负数:比如-10
    • 原码:1 000 1010
    • 反码:1 111 0101 (原码除符号位不变,其余位取反)
    • 补码:1 111 0110 (补码 = 反码 + 1),这也是计算机中对于数值-10最终的存放形式
  • 公式:
    • 当 X >= 0, [ X ] 补 = X               零和正数不用变换
    • 当 X < 0 ,  [ X ] 补 = X + 2^n      n是补码的位数
  • 数值溢出:
    • 超过数据所能表达的范围,称为溢出,就像钟表,最大值和最小值是相邻的

#include <stdio.h>

int main()
{
    char ch;

    //符号位溢出会导致数的正负发生改变
    ch = 0x7f + 2; //127+2
    printf("%d\n", ch);
    //    0111 1111
    //+2后 1000 0001,这是负数补码,其原码为 1111 1111,结果为-127

    //最高位的溢出会导致最高位丢失
    unsigned char ch2;
    ch2 = 0xff + 1; //255+1
    printf("%u\n", ch2);
    //      1111 1111
    //+1后 10000 0000, char只有8位最高位的溢出,结果为0000 0000,十进制为0

    ch2 = 0xff + 2; //255+2
    printf("%u\n", ch2);
    //      1111 1111
    //+1后 10000 0001, char只有8位最高位的溢出,结果为0000 0001,十进制为1

    return 0;
}

运行结果:

表达范围:

在64位机中,int型变量占4字节,就是32位,

  • 当表示负数时,最高位为符号位(符号位为1),最小的负数是 1000 0000 0000 0000 0000 0000 0000 0000 而在计算机中是以补码的形式存储的,即-2147483648
  • 当表示正数时,最高位为符号位(符号位为0),最大的正数是 0111 1111 1111 1111 1111 1111 1111 1111 即2147483647

Q:

      计算机为什么使用补码?

A:

      采用补码可以简化计算机硬件电路设计的复杂度

      解决了数字 0 在计算机中非唯一编码的问题

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值