37

C语言核心技术-变量和数据类型 - ittimeline - 博客园

 4 years ago
source link: https://www.cnblogs.com/ittimeline/p/11783696.html?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

C语言核心技术-变量和数据类型

C语言核心技术

2.1 计算机的计算单位

2.1.1 容量单位

在购买电脑时,通常会选择高配置的内存、硬盘。例如2019款15寸的MacBookPro已经可以选配32G内存和4T的固态硬盘,而这里的32G和4T就是计算机常用的容量单位。

在物理层面,我们使用高低电平来记录信息,通常使用高电平表示1,低电平表示0,因此在计算机底层只能认识0,1两种状态。而0,1能够表示的内容太少,迫切需要更大的容量表示方法,因此诞生了字节(Byte),千字节(KB),兆字节(MB),吉字节(GB),太字节(TB),拍字节(PB),艾字节(EB),除了bit和Byte之外,从Byte到KB,MB,GB,TB,PB,EB,它们的换算都是以2的10次方即1024换算的。

1YB=1024ZB
1ZB=1024EB
1EB=1024PB
1PB=1024TB
1TB=1024GB
1GB=1024MB
1MB=1024KB
1KB=1024B
1Byte=8bit
  • 位(bit)是最小的计算机容量单位,通常用于门电路,只能存储0或者1
  • 字节(Byte)、千字节(KB)、兆字节(MB)表示网络传输,文件大小。字节是最基本的容量计量单位。
  • 吉字节(GB)通常用于表示计算机内存、磁盘的容量单位
  • 太字节(TB),拍字节(PB)通常是用于表示云盘、移动硬盘的容量单位
  • 艾字节(EB)通常是用于表示数据中心的容量单位

现在通常笔记本的内存通常是8G,16G,32G,64G等等,而运行在笔记本之上的操作系统普遍都是64位的,因为32位系统只能使用4G内存,下面是4G的内存换算

4G=2^2 * 2^10 * 2^10 * 2^10 =4*1024*1024*1024=2^32

在购买内存或者买移动硬盘时,通常使用的存储单位就是GB或者是TB,
但是在买4T的移动硬盘时,实际的可用容量却只有3T多,因为计算机的存储单位是以2的10次方(即1024)换算,而硬盘厂商们是以1000为换算单位。

4T的硬盘换算成位如下所示

4T=4*1024GB*1024MB*1024KB*1024B*8bit

而硬盘厂商的实际容量

4T=1000*1000*1000*1000*8

因此实际的可用容量是

4*1000*1000*1000*1000/1024/1024/1024/1024≈3.63T

而在一些互联网巨头(例如国内的BAT,国外的亚马逊、苹果、微软、谷歌,脸书)公司中,可能使用到比TB更大的海量数据,也就是PB或者EB,它们的换算单位如下所示。

1PB=1024TB
1EB=1024PB

2.1.2 速度单位

  • 网络速度
    网络常用的单位是Mbps
    而网络带宽提供商(例如长城宽带)声称的百兆带宽实际上是100Mbit/s,但是100M光纤测试的峰值速度只会有12.5MB/s,它们之间的换算是100Mbit/s=(100/8)MB/s=12.5MB/s。

  • CPU速度
    CPU的速度一般是由CPU的时钟频率所体现的,而时钟频率的单位是赫兹(Hz),目前主流的CPU时钟频率一般都在2GHz以上,而赫兹(Hz)其实就是秒分之一,也就是每秒钟的周期性变动重复次数的计量。
    GHz即十亿赫兹(10^9Hz),2GHz就是二十亿赫兹,也就是说2GHz的CPU每秒可以变化20亿次。

1Khz=1000hz
1Mhz=1000khz
1Ghz=1000Mhz

2.2 数据类型

2.2.1 数据为什么要分类

数据类型就是给数据分类,其目的就是合理的利用计算机的内存空间,提高存储效率。
类型是抽象的概念,类型有大小,但是没有空间,系统不会给类型分配空间,但是会给类型定义的变量分配空间,例如定义变量 int age =28;时系统会给age变量分配四个字节的空间。
不同的数据类型占据不同的内存大小,其存储数据的极限也不一样、能够执行的运算也是不相同的。

2.2.2 C语言常用基本数据类型

C语言中基本数据类型有整型、浮点型、字符型,布尔型。其他的类型都是由基本数据类型封装而来的。

其中整数按照不同的字节大小有short,int,long,long long,其中long long 是C99标准支持。
浮点数按照精度不同有float,double,其中float表示单精度浮点型,double表示双精度浮点型。
字符只有char表示,用于存储单个字符。
布尔使用bool表示,C语言中的0表示false,1表示true。

2.2.3 sizof关键字查看数据类型占据的内存容量

C语言提供了提供了sizeof()关键字来获取数据类型占据的内存空间。
sizeof()中可以传数据类型名或者变量名,当传递变量名实际上是求变量类型的大小。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*
    sizeof关键字的使用
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/25
*/
int main(int argc, char* argv[])
{
    //使用printf函数输出各个基本数据类型占据的字节数量
    printf("char 占据的字节数量是%d\n", sizeof(char));
    printf("short 占据的字节数量是%d\n", sizeof(short));
    printf("int 占据的字节数量是%d\n", sizeof(int));
    printf("long 占据的字节数量是%d\n", sizeof(long));
    printf("long long 占据的字节数量是%d\n", sizeof(long long));
    printf("float 占据的字节数量是%d\n", sizeof(float));
    printf("double 占据的字节数量是%d\n", sizeof(double));
    printf("bool 占据的字节数量是%d\n", sizeof(bool));
    system("pause");
    return 0;
}

需要注意的是C语言相同的数据类型在不同的操作系统环境下占据的空间是不一样的。在Visual Studio 2019中集成了32位编译器和64位编译器,C程序默认是以32位运行的。

X86表示32位

32位:sizeof()关键字的运行结果

32位 sizeof()关键字

如果想要切换到64位下运行,只需要将X86换成x64即可

X64运行

64位:sizeof()关键字的运行结果

64位 sizeof()关键字

在Windows平台下long类型无论是在32位还是64位都是占据四个字节,而Linux(Ubuntu18.04)则是占据8个字节。

Ubuntu18.04下sizeof()关键字测试

//
// Created by guanglei on 8/28/19.
//
#include <stdio.h>
#include <float.h>
#include <stdbool.h>
int main(){

    printf("char 占据的字节数量是%d\n",sizeof(char));
    printf("short 占据的字节数量是%d\n",sizeof(short));
    printf("int 占据的字节数量是%d\n",sizeof(int));
    printf("long 占据的字节数量是%d\n",sizeof(long));
    printf("long long 占据的字节数量是%d\n",sizeof(long long));
    printf("float 占据的字节数量是%d\n",sizeof(float));
    printf("double 占据的字节数量是%d\n",sizeof(double));
    printf("long double 占据的字节数量是%d\n",sizeof(long double));
    printf("bool 占据的字节数量是%d\n",sizeof(bool));

    return 0;
}

程序运行结果

Ubuntu18.04下sizeof()关键字测试

2.2.4 数据的有符号和无符号

有符号表示数据有正负之分,数值二进制的最高位(左边第一位)为符号位,0表示整数,1表示负数,其他位为负数。以两个字节的数据1为例子,其二进制表示为0000 0000 0000 0001,因为是正数,因此最高位是0,-1的二进制表示为1000 0000 0000 0001,因为是负数,因此最高位是1。
无符号数表示数据没有正负之分,全是正数(即大于等于0的数),无符号数没有符号位,全是数据位。以两个字节的数据1为例子,其二进制表示为0000 0000 0000 0001。

C语言中的整数常量默认都是有符号的,如果要使用无符号的常量,需要在常量值后面添加U后缀。
C语言中的整数变量默认都是有符号的,如果要使用无符号的变量,需要在变量类型前面加上unsigned关键字。

有符号整数常量和无符号整数常量

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    有符号整数常量和无符号整数常量
    常量默认是有符号数
    如果要使用无符号使用U结尾
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/11/02
*/
int main(int argc, char* argv[])
{
    // 10默认是有符号
   //有符号整型
    printf("%d \n", 10);
    //10U是无符号数 printf输出无符号int 使用格式 %u
    printf("%u \n", 10U);

    // 有符号长整型
    printf("%ld \n", 10L);
    //无符号长整型
    printf("%lu \n", 10UL);
    system("pause");
    return 0;
}

有符号和无符号变量

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    变量默认是有符号的,如果要声明无符号的变量,使用unsigned声明
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/11/02
*/
int main(int argc, char* argv[])
{

    //整数变量默认是有符号的
    int age = 26;
    //无符号整数变量
    unsigned int data = 39;
    printf("age =%d \n",age);
    printf("date = %u \n",data);
    system("pause");
    return 0; 
}

2.2.5 数据类型的极限

数据类型都有其存储范围(即存储的最大值和最小值),C语言中的limits.h和float.h头文件中分别定义了整数和浮点数的极限。在使用数据类型时,切勿超过其极限,否则会造成程序异常。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
/*

    数据类型的极限
    数据类型都有其存储范围(即存储的最大值和最小值),C语言中的limits.h和float.h头文件中分别定义了整数和浮点数的极限。在使用数据类型时,切勿超过其极限,否则会造成程序异常。


    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/11/02
*/
int main(int argc, char* argv[])
{
    printf("int能存储的最大值是%d\tint能存储的最小值是%d,占据的字节数量是%d\n \n\n\n", INT_MAX, INT_MIN, sizeof(int));
    printf("double能存储的最大值是%e\t double能存储的最小值是%e,double占据的字节数量是%d\n \n \n\n", DBL_MAX, DBL_MIN, sizeof(double));

    printf("unsigned char 表示的最大值是%d\n", UCHAR_MAX);
    //无符号的char存储的最大值是255 这里超过了最大范围,输出的结果不是预期的256,,而且0
    unsigned char num = 255 + 1;
    printf("num = %d\n", num);

    system("pause");
    return 0;
}

2.3 常量

任何基本类型都有变量和常量两种类型
常量是其值在程序运行期间不能修改,例如小数3.14,字符'a'都是常量,常量之所以不能被修改,是因为常量是在文字常量区。
内存在存储数据时,考虑到数据不同的用途和特点,把内存存储区域分为各种区域:栈区、堆区、代码区、文字常量区、全局区。每个区域的数据类型都有各自的特点。

在日常开发中常用的常量有字符常量、短整型常量、整型常量、长整型常量、单精度浮点型常量以及双精度浮点型常量。

结合C语言提供的printf函数以及格式符实现格式化输出常用基本数据类型的常量值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
    日常开发中的基本数据类型的常量
    
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/28
*/
int main(int argc, char* argv[])
{

   //%c 用于输出一个字符,这里输出字符a
    printf("char c= %c \n", 'a');
    //%hd用于输出短整型
    printf("short s= %hd \n", 10);
    //%d用于输出整型
    printf("int i= %d \n", 100);
    //%ld用于输出长整型
    printf("long l= %ld \n", 10000);
    //%lld用于输出长长整型
    printf("long ll=%lld \n", 100000000000000000);
    //%f用于输出单精度浮点型
    printf("float f= %f", 3.14f);
    //%ld用于输出双精度浮点型
    printf("double d= %lf", 3.14);
    //常量一旦定义后不能被修改(赋值)
    //10 = 20;
    system("pause");
    return 0;
}

2.4 变量

2.4.1 变量的本质

生活中随处可见变量,例如股市的涨跌,游戏人物的武力值都是不断变化的。
变量就是程序运行时其值可以被修改,而且在定义变量时系统会根据变量类型开辟内存空间,变量可以进行读写操作,在同一时刻,内存中的变量只能存储一份值。如果对变量进行修改,新值会覆盖旧值。

这里可以通过一段程序结合Visual Studio 2019的调试功能查看内存中值的变化理解变量及其读写数据本质。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    变量在内存中的存储以及读写操作的本质
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/28
*/
int main(int argc, char* argv[])
{
    int num = 20;
    //查看num的内存地址
    printf("整数变量num的地址是%p\n", &num);
    printf("整数变量num = %d\n", num);
    num = 30;
    printf("修改之后整数变量num的值是%d\n", num);
    system("pause");
    return 0;
}

运行程序前,首先设置断点。

设置断点

然后启动程序,查看控制台输出num的变量地址
然后通过Visual Studio 2019的调试->窗口->内存菜单查看内存,并在地址栏中输入整数变量num的地址,查看变量值。Visual Studio 2019中查看内存的值默认是一字节,不带符号,十六进制显示。

查看变量值

可以通过鼠标右键设置成四字节、带符号显示。

四字节,带符号显示

当程序执行num=30时,内存中的值被修改了

修改变量

程序运行结果

程序运行结果

2.4.2 变量的定义

变量在使用前必须要先定义即声明并赋初始值,否则会出现编译错误。定义变量时系统会针对变量的类型开辟指定的内存空间。

变量定义的目的是让变量在系统中存在,变量定义后系统给变量开辟内存空间,变量定义的格式是 类型名+类型名,例如 int number,number就是变量名,类型为int,意味着编译器会针对number变量开辟4个字节的内存空间。
变量名的本质就是空间内容的别名,操作变量就是操作变量代表的那块内存空间。

在定义变量时,变量名还要遵守以下的命名规则。

  • 变量名由字母、数字、下划线组成。
  • 变量名不能以数字开头。
  • 变量名不能是关键字,关键字是被C语言赋予了特殊的含义,但是可以包含关键字,Visual Studio 2019中蓝色的都是关键字。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    变量的命名规范
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version
*/
int main(int argc, char* argv[])
{
    // 合法的标识符
    int number;
    //见名知意
    int age;
    char ch;
    double db;
    //变量名不能是关键字
    //int void;
    //变量名不能以数字开头
    //int 1num;
    /****************************************编译器特性*******************************/
    //VC支持中文变量,GCC不支持中文命名
    int 年龄 = 29;
    printf("年龄 =%d\n", 年龄);
    //在老版(C++11之前)的编译器中,变量声明必须放在函数调用之前
    /****************************************编译器特性*******************************/
    //声明多个变量
    int one, two, three;
    system("pause");
    return 0;
}

2.4.3 变量的初始化

变量使用前必须赋值完成初始化,即变量定义时就给变量赋值,例如int age=0;,否则会发生编译错误:error C4700: 使用了未初始化的局部变量。
定义变量时赋值叫变量的初始化,而定义完成以后再赋值不叫初始化,只是单纯的赋值。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    变量的定义
    变量的初始化:定义时赋值
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/28
*/
int main(int argc, char* argv[])
{
    //变量定义的语法  变量类型 变量名
    int number;
    //变量使用前必须定义并初始化,初始化即定义时给变量赋值,否则会发生编译错误
    //printf("number = %d",number);


     //定义时赋值叫变量的初始化
    int age = 26;

    //变量定义
    int val;
    //定义完成后再赋值就不叫初始化,只是单纯的赋值
    val = 12;
    
    system("pause");
    return 0;
}

在定义变量时可以针对变量的类型赋对应的初始值,例如整数赋值为0,浮点数赋值为0.0,字符类型可以初始化为'\u00'。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
    基本数据类型变量的初始化
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/28
*/
int main(int argc, char* argv[])
{
    //变量初始化时如果类型为整数,推荐初始化为0
    int number = 0;
    double dbl = 0.0;
    //字符型推荐初始化为\u00
    char c = '\u00';


    system("pause");
    return 0;
}

日常开发中通常都是先定义再使用变量,而且通常都需要在定义时初始化即赋值,如果使用了一个没有赋值的变量,程序会发生编译错误。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    变量使用的注意事项
    变量在使用前必须初始化赋值,否则会出现C4700错误-> "使用了未初始化的局部变量"
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/28
*/
int main(int argc, char* argv[])
{
    //声明一个整数变量并未初始化
    int num;
    //编译错误错误	C4700	使用了未初始化的局部变量“num”
    printf("num =%d\n", num);
    system("pause");
    return 0;
}

2.4.4 变量的声明

变量的声明表示告诉编译器该变量已经存在,此处通过编译,但是不会再开辟内存空间。
变量的声明分为自动识别和显示声明两种,日常开发中通常使用自动识别声明变量。
如果变量定义在使用前面,编译器可以自动识别变量声明,因为编译器在编译时是从上到下逐语句编译。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*


    声明变量-自动识别
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/28
*/
int main(int argc, char* argv[])
{
    //编译器从上到下逐行编译,
    int number = 10; // 变量的定义
    //变量的定义在使用之前,此处会自动识别变量的声明
    printf("number = %d \n", number);//变量的使用
    system("pause");
    return 0;
}

如果变量的定义不再使用的前面,可以使用extern关键字显示声明变量,在声明时不用赋值,否则会引发变量“重定义,多次初始化的编译错误”。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
    声明变量-显示化声明变量
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/28
*/

//显示声明变量,不用赋值,告诉编译器在使用到该变量的地方编译通过
extern int age;

int main(int argc, char* argv[])
{
    printf("age = %d", age);
    system("pause");
    return 0;
}

//变量的定义在使用之后
int age = 26;

但是如果最终变量没有定义在使用之后,程序运行时还是会出现异常,例如这里如果注释int age = 26;就会出现 无法解析的外部符号 age。

2.4.5 变量的使用

变量的使用表示对变量的读写操作,所谓读就是获取变量的值,例如使用printf()输出变量的值,写就是赋值以及各种变量的运算,C语言中使用"="表示赋值,赋值是将右边的值赋值给左边的变量,也就是操作内存空间。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    变量的读写操作
    打印输出就是读操作
    赋值操作就是写操作
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/28
*/
int main(int argc, char* argv[])
{
    //变量赋值 就是变量的写操作
    int age = 26;
    //printf函数就是对变量的读操作
    printf("age = %d\n ", age);
    //=是将右边的值赋值给左边的变量
    int my_age = age;
    //这里也会打印输出my_age = 26
    printf("my_age = %d\n ", my_age);
    system("pause");
    return 0;
}

除此以外后续还会学习各种运算符,例如算术运算符、自增运算符、逻辑运算符、关系运算符、三元运算符、位运算符等等。

变量的算术运算操作

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*
    变量的算术运算
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/28
*/
int main(int argc, char* argv[])
{
    //定义两个整数变量
    int left = 10;
    int right = 20;
    //计算两个整数变量相加
    int result = left + right;
    //输出两个整数相加的结果
    printf("%d + %d = %d \n", left, right, result);
    result = right - left;
    //输出两个整数相减的结果
    printf("%d - %d = %d \n", right, left, result);
    system("pause");
    return 0;
}

2.5 读取键盘的输入

之前在定义整数变量并初始化值时只能写死一个值,整数变量建议初始化时为0,这样可以避免许多不必要的错误出现。
为了让程序变得更加灵活,这里引入C语言标准库函数scanf()函数实现基于终端字符界面的人机交互。当然日常应用(例如淘宝、京东)都是基于UI界面实现人机交互,但是底层处理的逻辑是一样的。

scanf()函数可以从键盘中读取用户输入的整数、小数、字符等等,该函数的参数需要传递 提取数据格式和变量地址两个参数,提取数据格式指的就是用户输入的数据类型,例如整数、小数等等,变量地址就是&变量名,&表示地址符号,变量名只能代表空间的内容,通过&变量名获取变量对应存储空间存储的值。
scanf()函数是阻塞式的,当用户输入数据之后,数据会存储到标准输入缓存区中,然后scanf()函数负责从标准缓冲区中拿指定格式的数据,如果用户不输入数据,那么程序会一直处于阻塞状态,直到用户输入数据后程序继续往下执行。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/*

    使用scanf函数读取用户从键盘输入的整数数据
    @author liuguanglei [email protected]
    @website ittimeline.net
    @version 2019/10/28
*/
int main(int argc, char* argv[])
{
    //变量初始化时如果类型为整数,推荐初始化为0
    int age = 0;
    printf("请输入你的年龄(按回车键结束)\n");//此时程序会进入阻塞状态
    //当用户输入数据并回车之后先到达标准输入缓冲区
    //scanf函数负责从标准缓冲区拿整数,此函数是阻塞的,即等到用户输入数据才会往下执行
    //%d表示提取键盘输入的数字
    //变量名仅仅代表变量的内容,如果想要获取变量的起始地址,需要使用&变量名
    scanf("%d", &age);

    printf("你的年龄是%d\n", age);
    system("pause");
    return 0;
}

程序运行结果

程序运行结果

2.6 计算机底层为什么只能识别二进制

我们目前主要使用的计算机都是大规模集成电路,是采用大规模和超大规模的集成电路作为逻辑元件的。集成电路按其功能、结构的不同,可以分为模拟集成电路、数字集成电路和数/模混合集成电路三大类。而我们的计算机主要是采用数字集成电路搭建的。逻辑门是数字逻辑电路的基本单元。常见的逻辑门包括“与”门,“或”门,“非”门,“异或”等等。通过逻辑门可以组合使用实现更为复杂的逻辑运算和数值运算。逻辑门可以通过控制高、低电平,从而实现逻辑运算。电源电压大小的波动对其没有影响,温度和工艺偏差对其工作的可靠性影响也比模拟电路小得多,所以相对稳定。因为数字计算机是由逻辑门组成,而逻辑电路最基础的状态就是两个——开和关。所以,数字电路是以二进制逻辑代数为数学基础。二进制的基本运算规则简单,运算操作方便,这样一来有利于简化计算机内部结构,提高运算速度。但是在日常开发中,通常都会使用八进制和十六进制,因为八进制和十六进制相对于二进制表示数据更加简洁,而且一个八进制表示三个二进制,一个十六进制表示四个二进制。例如1024使用二进制表示为0b100 0000 0000,使用八进制表示为02000,使用十六进制表示为0x400。

2.7 计算机常用进制及其转换

2.7.1 进制概述

进制的定义:进制是一种计数方式,也称为进位计数法或者位值计数法,使用有限数字符号表示无限的数值,使用的数字符号的数目称为这种进位制的基数或者底数,例如十进制就是由0-9十个数字组成。在计算机内存中,都是以二进制的补码形式来存储数据的,生活中以十进制方式计算的数据居多,例如账户余额,开发人员的薪水等等。计算的内存地址、MAC地址等等通常都是使用十六进制表示的,Linux系统的权限系统采用八进制的数据表示的。相同进制类型数据进行运算时会遵守加法:逢R进1;减法:借1当R,其中R就表示进制。

计算机常用进制的组成、示例和使用场景

进制名称 组成 数值示例 应用场景
二进制 0,1 1010 计算机底层数据存储
八进制 0-7之间的8个整数 010 linux权限系统
十进制 0-9之间的10个整数 12 整数
十六进制 0-9,a-f之间的10个整数加上6个字母 12f 数据的内存地

2.7.2 十进制转换二进制、八进制、十六进制

十进制转换二进制、八进制、十六进制可以采用短除法,即待转换的十进制数除以指定的进制(例如2,8,16),直到商数为0,求余数。

十进制101转换为二进制的计算过程

重复除以2 商数 余数
101/2 50 1
50/2 25 0
25/2 12 1
12/2 6 0
6/2 3 0
3/2 1 1
1/2 0 1

然后将余数的结果从下到上串联起来的结果:1100101,即十进制的101转换为二进制的结果为1100101

十进制的237转换为二进制

重复除以2 商数 余数
237/2 118 1
118/2 59 0
59/2 29 1
29/2 14 1
14/2 7 0
7/2 3 1
3/2 1 1
1/2 0 1

然后将余数的结果从下到上串联起来的结果:11101101,即十进制的237转换为二进制的结果为11101101。

2.7.3 二进制转八进制、十六进制

二进制转八进制是按照从右往左,每3位二进制对应1位八进制,因为2的3次方等于8

二进制整数11001100转八进制计算过程

11 001 100 =0314

二进制转十六进制是按照从右往左,每4位二进制对应1位十六进制,因为2的4次方等于16。

二进制整数1100 1110转十六进制计算过程

1100 1110 =0xce

2.7.4 八进制、十六进制转二进制

八进制转二进制是按照从右往左,每1位八进制对应3位二进制。

八进制整数0127转二进制整数计算过程

0127=001 010 111

十六进制转二进制是按照从右往左,每1位十六进制对应4位二进制。

十六进制整数0x12f转换为二进制整数计算过程

0x12f=0001 0010 1111

2.7.5 二进制、八进制、十六进制转十进制

首先明确不同进制的值是如何计算的,这里以十进制和二进制为例子,阐述它们的计算过程。

十进制整数1024

1024=1*10^3+2*10^1+4*10^0=1000+20+4=1024

二进制整数 10000000000

10000000000 =1*2^10=1024

二进制、八进制、十六进制整数转十进制整数是使用按权展开法计算的,这里以二进制数据01100101为例子。从右往左开始数,如果二进制位为1,则依次用1*2^n,n从0开始。

二进制整数01100101 转换为十进制整数的计算过程

01100101=126+1*25+1*22+1*20=64+32+4+1=101

八进制整数0127转换为十进制整数的计算过程

0127=1*8^2+2*8^1+7=87

十六进制整数0x12f转换为十进制整数的计算过程

0x12f=1*16^2+2*16^1+f*16^0=256+32+15=303

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK