-ciox.jpg)
【C】常量和变量
数据存储,常量和变量
1. 数据存储
1.1 计算机硬件基本知识
对于程序开发中,计算中重要的硬件组成是 CPU,内存(RAM)和硬盘(ROM)。任何的程序运行都需要 CPU 提供对应的执行能力和运算能力,同时内存提供程序的执行数据空间,硬盘作为永久性数据存储设备完成数据存储。
1.2 计算机中最小数据存储单位
计算机中规定,最小的数据存储单位是【字节 byte】,一个字节对应 8 个二进制位/ bit 位,嵌入式开发中常用的数据存储单位
- KB ==> 1024 Byte
- MB ==> 1024 KB
- GB ==> 1024 MB
正常开发中常用数据单位一般是 KB 和 MB ,后续到驱动开发或者较大型的嵌入式项目开发涉及到 GB 单位
1.3 开发中的常用数据进制
在嵌入式开发中,常用的数据进制有
- 十进制
- 二进制
- 八进制
- 十六进制
进制仅是当前数据的描述形式和描述方法。
1.3.1 不同进制数据的使用要求或者文本描述要求
数据进制 | 基数范围 | 进制关系 |
---|---|---|
十进制 | 0 ~ 9 | 逢 10 进一 |
二进制 | 0,1 | 逢 2 进一 |
八进制 | 0 ~ 7 | 逢 8 进一 |
十六进制 | 0 ~ 9, A ~ F | 逢 G(16) 进一 |
tips:A => 10, B => 11, C => 12, D => 13, E => 14, F => 15
十进制使用
- 正常使用和生活中数学十进制使用形式一致。
八进制使用
- 【要求】在开发中八进制数据要求 0 开头,告知编译器当前数据为八进制数据
- 【特殊】在特定情况下,0 可以省略,例如 chmod 775
0777 0666 0123
十六进制【重点】
- 【要求】在开发中十六进制数据要求 0x 开头,告知编译器当前数据为十六进制数据
- tips: 十六进制使用的英文字母 A ~ F,不区分大小写
0xABCD 0x1234 0xab123df
二进制
- 【要求】开发中一般情况下不会直接使用二进制数据形式,通常情况下会采用十六进制方式来描述二进制数据内容,当前数据形式为【文档中的数据展示形式】
- 一般情况下二进制 4 位为一个组合,8 位为一个整体,另外为了明确告知,通常情况下会结尾使用 (2) 告知当前文本数据为二进制数据内容
0110 1100(2) # 文档中描述二进制的推荐形式,开发中无法使用 0011 1011 1100 1000(2)
1.3.2 不同进制之间的转换
进制转换中最重要的是
- 【重点,掌握】十六进制和二进制之间转换
位号 | 3 | 2 | 1 | 0 |
---|---|---|---|---|
数值 | 8 | 4 | 2 | 1 |
A => 10, B => 11, C => 12, D => 13, E => 14, F => 15
十六进制的一位对应二进制的四位
案例一: 十六进制转二进制
0x9FDE #十六进制的每一位数据分析对应数值,使用二进制 0 ~ 3 位数据进行累加计算,哪一位使用,哪一位为 1 # 9 ==> 8 + 0 + 0 + 1 ==> 1001 # F(15) ==> 8 + 4 + 2 + 1 ==> 1111 # D(13) ==> 8 + 4 + 0 + 1 ==> 1101 # E(14) ==> 8 + 4 + 2 + 0 ==> 1110 二进制结果为 1001 1111 1101 1110(2)
案例二: 二进制转十六进制
1101 1110 1010 1000(2) # 1101 ==> 8 + 4 + 0 + 1 ==> 13 ==> D # 1110 ==> 8 + 4 + 2 + 0 ==> 14 ==> E # 1010 ==> 8 + 0 + 2 + 0 ==> 10 ==> A # 1000 ==> 8 + 0 + 0 + 0 ==> 8 ==> 8 十六进制结果为 0xDEA8
- 八进制和二进制之间转换
位号 | 2 | 1 | 0 |
---|---|---|---|
数值 | 4 | 2 | 1 |
- 八进制的一位对应二进制的三位
案例一: 八进制转二进制操作
07562 # 7 ==> 4 + 2 + 1 ==> 111 # 5 ==> 4 + 0 + 1 ==> 101 # 6 ==> 4 + 2 + 0 ==> 110 # 2 ==> 0 + 2 + 0 ==> 010 二进制结果为 0000 1111 0111 0010(2)
案例二: 二进制转换八进制操作
0110 1100 1011 0111(2) # 按照八进制一位对应二进制三位规则,从数据末尾开始拆解二进制内容 000 110 110 010 110 111 # 从前向后进行 二进制转换进制操作 # 110 ==> 4 + 2 + 0 ==> 6 # 110 ==> 4 + 2 + 0 ==> 6 # 010 ==> 0 + 2 + 0 ==> 2 # 110 ==> 4 + 2 + 0 ==> 6 # 111 ==> 4 + 2 + 1 ==> 7 八进制结果为 066267

1.4 原码,反码和补码【当小说看】
计算机之父冯·诺依曼
- 二进制思想
- 文件操作思想
冯·诺依曼提出原码,反码和补码来降低计算机的运算逻辑复杂度,要求所有的数据都采用补码形式参数。以整数为例讲解原码,反码和补码。
正整数 118 ==> 0111 0110(2),在计算机中正整数原码,反码和补码一致,在计算机中存储 118 对应的内存情况为
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|
0 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |
负整数 -118 补码数据需要进行一定的计算得到,有固定要求和格式
原码:负整数的原码是对应正整数二进制数据为基准,最高位改为符号位 1
118(10) ==> 0111 0110(2) # 取 118 正整数二进制使用,最高位改为 1 表示负数符号位 -118(10) ==> 1111 0110(2)
-118 原码为 1111 0110(2)
反码: 原码除符号位之外,其他位置按位取反,0 变 1,1 变 0
-118(10) ==> 1111 0110(2) 反码:1000 1001(2)
-118 反码为 1000 1001(2)
补码: 反码 + 1
-118(10) ==> 1000 1001(2) 反码 + 1 ==> 1000 1001 + 1 ==> 1000 1010
-118 在内存中的存储形式为
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 |
计算机是利用反码形式完成相对应的数据计算,可以将 118 +(-118) 行为根据内存的数据内存内容进行分析得到
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
---|---|---|---|---|---|---|---|---|---|---|
118 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | ||
+ | -118 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2. 常量
2.1 常量概述
生活中不会发生改变的量都是常量,或者可以说开发中无法修改的数据是常量。
2.2 生活中的常量
- 数值常量
- 整数
10, 20, 30, 1, 2, 3, -1, -2, -3
- 小数/浮点数
3.1415926 0.618 9.8
- 文字/字符常量
- 英文字符
A B C
- 数字字符
1 2 3
- 中文字符
你 我 他
- 文本/字符串常量
- "Break News: 湖人队浓眉交易独行侠东契奇"
- "落霞与孤鹜齐飞,秋水共长天一色。渔舟唱晚,响穷彭蠡之滨;雁阵惊寒,声断衡阳之浦"
- "先帝创业未半,而中道崩殂"
2.3 C/C++ 中常量要求
C/C++ 中基本常量类型有**【整数类型,浮点数据类型,字符类型和字符串类型】**
整数类型:
主要用于描述整数相关数值内容,数值常量
10 20 30 1 2 3
浮点类型
用于描述小数/浮点数常量形式
3.1415926 0.618 9.8
字符类型
【要求】在 C/C++ 中字符类型常量,要求使用英文单引号包含的单个元素
C/C++ 字符常量不支持中文,仅支持 ASCII 码(英文字母,数字字符,标点符号,特殊符号)
'A' 'B' 'C' '1' '2' '3'
字符串常量
【要求】在 C/C++ 中字符串常量,使用英文双引号包含的所有内容
虽然字符串支持中文,但是在实际开发中,中文出现的情况较少
"Input Parameter is invalid!" "北国风光,千里冰封,万里雪飘..."
2.4 常量代码演示
2.4.1 代码实现
/*
* 在当前的程序中导入 stdio.h 头文件
* 导入之后可以使用对应头文件中的相关资源,函数和功能
*/
#include <stdio.h>
/*
* argc argument count 参数个数
* argv argument value 参数数据
*/
int main(int argc, const char *argv[])
{
/*
* 常量有
* 整数常量,浮点数常量,字符常量,字符串常量
*/
printf("整数常量: %d\n", 2);
printf("整数常量: %d\n", 7);
printf("整数常量: %d\n", 3);
printf("浮点常量: %f\n", 3.5);
printf("浮点常量: %f\n", 4.5);
printf("字符常量: %c\n", 'A');
printf("字符常量: %c\n", '1');
printf("字符常量: %c\n", '!');
printf("字符常量: %c\n", '中');
printf("字符串常量: %s\n", "Input Parameter is Invalid!");
printf("字符串常量: %s\n", "哪吒票房92亿");
return 0;
}
2.4.2 编译执行目标 C 语言程序
编译,将 C 语言源文件编译满足当前系统环境下, CPU 可以识别的二进制可执行文件。
编译操作格式
qf@qf:~/桌面/Code/Day02$ gcc 01-第一行代码和常量.c # gcc 是 C 语言编译工具 # gcc C语言源文件
编译完成之后可以得到默认文件名称为 a.out 可执行文件
qf@qf:~/桌面/Code/Day02$ ls -l 总用量 16 -rw-rw-r-- 1 qf qf 1236 2月 12 14:35 01-第一行代码和常量.c -rwxrwxr-x 1 qf qf 8328 2月 12 14:39 a.out
执行目标二进制可执行文件,CPU 执行目标程序。
目标执行对应的 a.out 可执行二进制文件,格式
qf@qf:~/桌面/Code/Day02$ ./a.out # . 表示当前工作目录 # ./ 告知计算机,执行目标可执行文件
2.5 字符数据
2.5.1 字符集
对于计算机而言,每一个文字都是一个图片,在真实的程序中,文字对应的都是一个唯一的编码,计算机根据编码以及当前默认使用的字符集,展示对应的文字图片。开发中常用,常见的字符集
- ASCII : 嵌入式开发中使用最多的编码,内容是英文字母大小写,数字字符,标点符号,特殊字符,任何一个可以在计算机中使用的字符集,必须支持 ASCII
- GBK:中国国标,主要包括中文简体字和少数民族文字
- UTF-8:万国码,后续开发中如果涉及到国际化开发,需要使用 UTF-8
- BIG5:中文繁体字编码,主要用于中国台湾,中国香港,中国澳门
2.5.2 ASCII 内容使用要求
- 在开发中使用任何字符数据,请使用字符本身,不允许使用对应编码值。会导致代码阅读性极差,需要严格遵守【数据类型一致化原则】
- ASCII 码中编码 0 ~ 31 是不可见字符,对应的是键盘或者特殊用途符号,重点是编号为 0 的字符,nul
- 数字字符在 ASCII 码中对应的顺序是 '0' ~ '9'
- 英文字符,大写字母的编码值小于小写字母
- 英文字符在 ASCII 大小写之间非连续存在,大写 'Z' 到小写 'a' 之间有其他字符。
2.5.3 转义字符【了解】
- 本身基本特定含义的字符转换为无意义状态/仅字符状态,常用有
- 双引号转义操作
- 单引号转义操作
- 转义标记字符转义操作
- 特定字符使用转义操作,转换之后带有特定含义
- \n 换行
- \r 回车
- 要求文本数据传输过程中,要求结尾必须是 \n\r or \r\n ,End Of File
- \t 制表符 tab 键
3. 变量【小重点】
3.1 变量的概念
一杯水就是一个变量,水的容量会根据情况发生改变
- 存在约定俗成的名称
- 变量本身是一个容器,存储的数据是一个变化的内容
- 不同的容量,不同的单位,支持的数据范围不同。
3.2 变量分类
基本数据类型变量分类和常量分类一致
- 整数类型
- 浮点数类型
- 字符类型
3.3 变量的定义格式
数据类型 变量名 = 初始化数据;
- 数据类型:明确约束当前变量可以存储的数据类型,有且只允许存储对应类型数据,请严格遵守【数据类型一致化要求】
- 变量名: 【约定俗成,见名知意】,全英文。操作使用当前变量的名称,具备一定范围的唯一性。
- = : 赋值号,将赋值号右侧的数据赋值给左侧的变量
- 初始化数据:针对于当前变量数据类型,和业务场景所需的必要初始值。后续开发中任何一个变量必须在定义之后,进行初始化操作,避免【野值】问题。
3.4 基本数据类型
3.4.1 整数类型
- 在 C/C++ 中整数类型计算机默认为
int
类型/标准整型,除非当前整数类型超出int
存储范围,会自动选择采用long
类型- int 数据类型在 32 位机及其以上占用内存字节数为 4 个字节,如果是 16 位机占用 2 个字节,8 位机占用 1 字节。
- long 数据类型在 64 位机可以使用,占用内存为 8 个字节,如果是 32 位机占用 4 个字节。
- 后续开发中使用到芯片有 STM32 GD32 ESP32,可以认为 long 类型在以上芯片中都是 int 类型,还会使用到 ARM 相关芯片 RK3399 RK3588,ARM芯片都是 64 机,支持 long 类型
数据类型 | 占用内存字节数 | 存储数据范围 |
---|---|---|
short | 2字节(16bit) | 0 ~ 65535 or -32768 ~ 32767 |
int | 4字节(32bit) | 0 ~ 2^32 - 1 or -2^31 ~ 2^31 - 1 |
long | 8字节(64bit) | 0 ~ 2^64 - 1 or -2^63 ~ 2^63 - 1 |
面试题: 请问 int 类型占用多少个字节
int 类型在 32 位机及其以上,占用 4 个字节,如果是 16 位机占用 2 个字节,8 位机占用 1 字节
#include <stdio.h>
int main(int argc, const char *argv[])
{
// 数据类型 变量名 = 初始化数据;
// n ==> num ==> number
short n1 = 10;
int n2 = 100;
long n3 = 10000;
printf("n1 = %d\n", n1);
printf("n2 = %d\n", n2);
printf("n3 = %ld\n", n3);
return 0;
}
- 感谢你赐予我前进的力量