分享

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

 昵称67168469 2019-11-12

计算机的计算单位

容量单位

在购买电脑时,通常会选择高配置的内存、硬盘。例如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换算的。

  • 位(bit)是最小的计算机容量单位,通常用于门电路,只能存储0或者1

  • 字节(Byte)、千字节(KB)、兆字节(MB)表示网络传输,文件大小。字节是最基本的容量计量单位。

  • 吉字节(GB)通常用于表示计算机内存、磁盘的容量单位

  • 太字节(TB),拍字节(PB)通常是用于表示云盘、移动硬盘的容量单位

  • 艾字节(EB)通常是用于表示数据中心的容量单位

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

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

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

而硬盘厂商的实际容量

因此实际的可用容量是

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

速度单位

  • 网络速度网络常用的单位是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亿次。

数据类型

数据为什么要分类

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

C语言常用基本数据类型

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

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

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

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

需要注意的是C语言相同的数据类型在不同的操作系统环境下占据的空间是不一样的。在Visual Studio 2019中集成了32位编译器和64位编译器,C程序默认是以32位运行( https://link.zhihu.com/?target=https%3A//jq.qq.com/%3F_wv%3D1027%26k%3D5n2xgg8 )的。

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

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

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

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

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

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

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

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

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

程序运行结果

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

数据的有符号和无符号

有符号表示数据有正负之分,数值二进制的最高位(左边第一位)为符号位,0表示整数,1表示负数,其他位为负数。以两个字节的数据1为例子,其二进制表示为0000 0000 0000 0001,因为是正数,因此最高位是0,-1的二进制表示为1000 0000 0000 0001( https://link.zhihu.com/?target=https%3A//jq.qq.com/%3F_wv%3D1027%26k%3D5n2xgg8 ),因为是负数,因此最高位是1。无符号数表示数据没有正负之分,全是正数(即大于等于0的数),无符号数没有符号位,全是数据位。以两个字节的数据1为例子,其二进制表示为0000 0000 0000 0001。

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

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

有符号和无符号变量

数据类型的极限

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

常量

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

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

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

变量

变量的本质

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

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

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

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

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

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

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

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

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

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

程序运行结果

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

变量的定义

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

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

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

  • 变量名由字母、数字、下划线组成。

  • 变量名不能以数字开头。

  • 变量名不能是关键字,关键字是被C语言赋予了特殊的含义,但是可以包含关键字,Visual Studio 2019中蓝色的都是关键字。

变量的初始化

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

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

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

变量的声明

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

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

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

变量的使用

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

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

变量的算术运算操作

读取键盘的输入

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

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

程序运行结果

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

计算机常用进制及其转换

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

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

进制概述

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

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

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

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

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

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

十进制的237转换为二进制

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

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

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

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

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

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

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

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

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

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

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

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

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

十进制整数1024

二进制整数 10000000000

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

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

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

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多