前情回顾:在0级的时候,我们成功编写了第一个程序"Hello World"
问:如何深入理解 unsigned int a = 13; ?
概念
变量是什么?
答:变量用于存储数据,方便后续修改。可以说有了变量,程序才是有记忆的(例如我们计算了1+1的和,只要变量存了这个和,后续就不用重新计算)
基本格式:
数据类型 变量名 = 初始值;
数据类型
C语言中数据类型分:
1、基本数据类型:整型(10,-5)、浮点型(9.9,10.0)、字符型(‘A’,'B')
2、复合数据类型有:结构体、枚举、共用体
先来学基本数据类型,请看下表格:
1B = 8b(1字节=8位)
注:C语言是强类型,规定了什么类型的变量,就只能存什么样的数。
要存 字符就用char型:char a = 'A';
要存 有符号整数(正负数)就用int型:int a = 10,b = -5;
要存 无符号整数(正数)就用unsigned int型:unsigned int a = 10;
要存 浮点数(带小数点的)就用float或double型:float a = 9.9; double b = 9.999;
使用sizeof()函数可以查看各数据类型所占的内存字节数,代码:
#include <stdio.h>
int main()
{
//%d是占位符,为后面的十进制数占个位置,显示时就替换该数
printf("char类型占%dB\n",sizeof(char)); // \n是换行符,相当于word文档中敲了个换行
printf("int类型占%dB\n",sizeof(int));
printf("float类型占%dB\n",sizeof(float));
printf("double类型占%dB\n",sizeof(double));
return 0;
}
结果:
变量
定义
变量定义是告诉编译器变量的数据类型和名字,并创建它;创建后,我们就能操作这个变量的内存空间。
数据类型 变量名;
示例:
char c; // 定义一个 char 型变量,变量名为 c
short int s; // 定义一个 short int 型变量,变量名为 s
int age; // 定义一个 int 型变量,变量名为 age
float f; // 定义一个 float 型变量,变量名为 f
double d; // 定义一个 double 型变量,变量名为 d
初始化
变量初始化,就是告诉编译器,这个变量指向的这块内存存放的初始值。
解析:如果不进行变量的初始化,该变量值一开始就是垃圾值。因为该内存空间很有可能被其他程序用过,留下了个毫无意义的数值,即垃圾值。初始化就是手动给它个有意义的数。
示例:
char c = 'a'; // 定义一个 char 型变量,变量名为 c, 并初始化为 'a'
short int s = -1; // 定义一个 short int 型变量,变量名为 s,并初始化为 -1
int age = 10; // 定义一个 int 型变量,变量名为 age,并初始化为 10
float f = 3.2f; // 定义一个 float 型变量,变量名为 f,并初始化为 3.2
double d = 3.2; // 定义一个 double 型变量,变量名为 d,并初始化为 3.2
注:在编程语言中,=不是等于的意思,而是赋值的意思,将右边的值赋给左边。
我们可以一个语句定义多个同数据类型的变量,并初始化
int a=5,b=10;
int c=6,d;
int c,d=7;
命名规范
变量名只能由字母(a~z,A~Z)、数字 (0~9)、下划线(_)组成。
注:数字不能作为开头!还有关键字不能作为变量名(例:int、float、enum....),并且C语言是区分大小写的,如Count与count被认为是两个不同的变量名。
以下标识符是合法的:i、a、count、 number_of_book、BOOK_NUMBER、sum100、_total。
以下标识符是非法的:
3com:非法,以数字开头。
char:非法,char是C语言的一个数据类型,是关键字
a*b:非法,*不能出现在变量名。
number of book:非法,变量名中不能有空格。
变量的使用
接下来,看一个简单的例子。
代码:
#include <stdio.h>
int main()
{
int a=1,b=2,sum; //变量定义及初始化
sum = a+b; //sum变量负责存a+b的值
printf("a+b=%d\n",sum); //打印sum的值
a = b; //将b的值赋给a
sum = a+b;
printf("a+b=%d\n",sum); //打印sum的值
return 0;
}
结果:
科学记数法
在数学中表示较大的数字时,常用科学计数法表示,例如1000记作。在c语言中,也可以使用科学记数法表示数,格式为e后加指数,指数可正可负。
代码:
#include <stdio.h>
int main()
{
int x = 1e3; //1×10的3次方
int y = 1000e-2; //1000×10的-2次方
printf("x=%d\n",x);
printf("y=%d\n",y);
return 0;
}
结果:
拓展
在计算机中,不管是数据,还是指令,都是用二进制存储的。所以我们先来学习进制转换,数据的编码格式(原码、反码、补码
进制转换
十进制转二进制
十进制是日常生活中常用的数,逢十进一;二进制是计算机认识的数,逢二进一。
方法一:权重法
例如:十进制数13转二进制,首先看出13=8+4+1,再根据二进制每位的权重,即可得二进制位:1101
方法二:除2取余,逆序排列
在数学上,可以通过 “除2取余,逆序排列” 的方法,下图就是十进制转二进制的方法:
所以十进制数557转二进制为:10001011101
二进制转十进制
二进制转十进制采用按权展开相加法,通过将每位二进制数字乘以其对应的2的幂次方(权重)后,最终相加实现转换。二进制数每一位的权值由右至左依次为。
例如:二进制数1101转十进制,根据权重从左往右为
编码格式
在计算机中,对数据是用编码格式存储的。例如:
1、有符号整数(正负数)用补码形式存的
2、无符号数(正数)用二进制形式存的
3、浮点数采用IEEE754标准(指数用补码,尾数用原码)存的
4、字符用ASCII码值(二进制形式)存的。
所以我们先学习一下原码、反码、补码、IEEE754标准和ASCII。
原码
原码是整数的编码格式,它直接用一个二进制数来表示一个整数。最高位是符号位(0正1负),其余位表示数值部分。技巧:将数转成二进制数,最高位加个符号位
1、正数的原码
例如:正数+13的原码表示
步骤:(1)正数原码符号位为0(2)13转二进制为1101(3加上最高符号位,所以+13的原码形式:0,1101
2、负数的原码
例如:负数-5的原码表示
步骤:(1)负数原码符号位为1(2)5转二进制为0101(3)加上最高符号位,所以-5的原码形式:1,0101
提示:除了熟练整数的原码格式,还要学会通过原码看出是哪个整数。
反码
反码是原码的反向表示,稍微了解即可,反码只是计算机为了方便进行原码和补码之间转换。
技巧:对于正数,反码与原码相等;对于负数,反码是将原码除了符号位外,其余位取反。
1、正数的反码
例如:正数+13的反码表示
步骤:(1)求出+13的原码形式:0,1101(2)正数原码与反码相等,所以+13的反码形式:0,1101
2、负数的反码
例如:负数-5的反码表示
步骤:(1)求出-5的原码形式:1,0101(2)除了符号位外,其余位取反(3)所以-5的反码形式:1,1010
口诀:正数反码与原码不变;负数将原码除了符号位,其他位所有取反
补码
补码是计算机中表示有符号整数的编码方式,它解决了原码和反码在表示和运算上的问题,使得加法和减法运算更高效。
技巧:对于正数,补码与原码相同;对于负数,补码是原码除了符号位取反后末位+1(即反码+1)
1、正数的补码
例如:正数+13的补码表示
步骤:(1)求出+13的原码形式:0,1101(2)正数补码与原码相等,所以+13的补码形式:0,1101
2、负数的补码
例如:负数-5的补码表示
步骤:(1)求出-5的原码形式:1,0101(2)除了符号位外,其余位取反。得反码:1,1010(3)反码末位+1,得补码形式:1,1011
口诀:正数不变;负数将原码除了符号位取反,末位再+1(也就是反码+1)
注意:补码和原码之间的相互转换,也是按口诀一样
IEEE754标准
IEEE 754标准是一种二进制浮点数算术标准,用于规定计算机中浮点数的存储格式、运算规则和舍入方式等内容。浮点数分为单精度(32位)、双精度(64位)。
整体分为符号(0正1负)、阶码(补码形式)、尾数(原码形式)。 接下来,我们来举个例子计算机是如何存单精度浮点数6.125。
例子:6.125转成IEEE754的单精度标准
步骤:
(1)6.125 是正数,因此符号位为 0
(2)十进制转二进制。整数部分6转二进制(除2取余,倒序排列):110;小数部分0.125转二进制(乘2取整,正序排列):001。因此6.125转二进制为110.001
(3)进行规格化。将二进制数规格化为科学计数法形式:。可以看出指数是e=2,再加上偏移量127,即E=e+127=129。E就是指数部分,转二进制为:1000 0001
(4)规格化后的尾数为1.10001,去掉隐含的1后为10001,将其填充到23位,尾数部分即10001000000000000000000
(5)组合,将符号位、指数部分和尾数部分组合到一起。6.125转IEEE754标准: 0100 0000 1100 0100 0000 0000 0000 0000,转换为十六进制表示:0x40c40000H
所以计算机中存6.125,真实存的是二进制数:0100 0000 1100 0100 0000 0000 0000 0000
ASCII码
ASCII码是一种基于英文字符的字符编码标准,用于将字符(包括字母、数字、标点符号以及一些控制字符)表示为计算机可以识别的二进制数。以下是ASCII码表,只需了解一下即可:
接下来,我们来举个例子,计算机是如何存字符字母A。
例子:字符'A'转二进制形式
步骤:
(1)查ASCII码,知英文字母A转十进制数为65
(2)将十进制数65转二进制:0100 0001
所以计算机中存‘A’,真实存的是二进制数:0100 0001
思考
问:如何深入理解 char a = 'A'; ?
char a = 'A';
解析:首先定义了一个char类型变量,然后变量名为a,初始值为'A',也就是目前变量a的内存中存了个字符'A'。
知识点:在计算机中,存储字符采用ASCII码值的二进制形式
步骤:
(1)根据char类型,操作系统给变量a分配一个1B(8位)的连续内存空间
(2)计算机将初始值字符'A'根据ASCII码值,再转换成8位二进制数形式:0100 0001
(3)计算机将字符A的二进制数形式0100 0001放入变量a的内存空间中
问:如何深入理解 int a = 13,b = -5; ?
int a = 13, b = -5;
解析:首先定义了两个int类型变量,一个变量名为a,初始值为10;另一个变量名为b,初始值为-5。int类型可以存储正数和负数,因为它最高位是符号位,整体占32位(1位符号、31位数字),所以表示的范围小一点。
知识点:在计算机中,存储有符号整数采用补码形式
步骤:
(1)根据int类型,操作系统给变量a分配一个4B(32位)的连续内存空间,也给变量b分配一个4B(32位)的连续内存空间
(2)有符号整数的补码形式。
将13转成补码形式:0,1101,因为int类型占32位,所以扩充成32位补码形式:0000 0000 0000 0000 0000 0000 0000 1101;
将-5转成补码形式:1,1011,因为int类型占32位,所以扩充成32位补码形式:1111 1111 1111 1111 1111 1111 1111 1011;
补码扩充:正数补0,负数补1
(3)计算机将补码形式0000 0000 0000 0000 0000 0000 0000 1101存入变量a的内存空间;将补码形式1111 1111 1111 1111 1111 1111 1111 1011存入变量b的内存空间。
问:如何深入理解 unsigned int a = 13; ?
unsigned int a = 13;
解析:首先定义了一个unsigned int类型变量,变量名为a,初始值为13。unsigned int类型只能存储正数,不能存储负数。因为它没有符号位,32位都用来表示数,所以正数的范围更大。
知识点:在计算机中,存储无符号整数直接用二进制形式
步骤:
(1)根据int类型,操作系统给变量a分配一个4B(32位)的连续内存空间
(2)计算机将十进制数13转成二进制:1101,因为unsigned int类型占32位,所以将其扩充成32位二进制数:0000 0000 0000 0000 0000 0000 0000 1101
(3)将二进制数0000 0000 0000 0000 0000 0000 0000 1101放入变量a的内存空间中
问:如何深入理解 float a = 6.125; ?
float a = 6.125;
解析:首先定义了一个float类型变量,变量名为a,初始值为6.125。float类型是单精度,所占内存4B,即32位(采用IEEE754标准,1位符号+8位指数+23位尾数)
知识点:在计算机中,存储浮点数采用IEEE754标准
步骤:
(1)根据float类型,操作系统给变量a分配一个4B(32位)的连续内存空间
(2)计算机根据IEEE754单精度标准,将6.125转为32位形式:0100 0000 1100 0100 0000 0000 0000 0000
(3)计算机将IEEE754单精度标准形式0100 0000 1100 0100 0000 0000 0000 0000放入变量a的内存空间中
在该系列中,文章的前部分采用简短的白话文讲解用法,而后部分采用更深入的角度讲解原理。思考是人类的结晶~如果你觉得有用,给我个点赞、收藏+关注哦~持续更新