嵌入式学习——C语言基础
二、数据类型、进制转换、类型转换
文章目录
前言
`
在嵌入式中,一般需要处理的数据都是一些文件、寄存器等,这就需要将这些数据类型进行转换。常见的数据类型有整数、浮点数、字符串、列表、元组等。这些数据类型之间也有相互转换的关系,比如整数可以转换为浮点数,字符串可以转换为元组等。
S学长,看看谁还不在学!!!
提示:以下是本篇文章正文内容
一、数据类型
C语言执行过程中是否可变 :分为 常量 和 变量
常量: 不变的量
变量: 存储数据,随时可变的
1.常量
- 整型常量和浮点型常量
整型: 123,0123,0x123ff
浮点型: 3.14,3.14e3,3.14E-2
- 符号常量(即宏替换)
#define PI 3.1415
#define LIM 32
- 字符型常量和字符串型常量
字符’a’,’\0’,’\n’,’\027’,’\x1ff’;
字符串”a”,”hello world!”
- 转义字符 :
\n' ----> 对n进行转义 ---> 换行
\b' ---> backspace 回撤一个
例子
abcdefg\bxy // abcdefxy
'\t' : 格式 : 制表符 满8个位
adbdf\txxy // adbdf xxy
'\r' : 回车,跳到行首
abcedefe\rhfehjfehwv // hfehjfehwv
'\\' : 字符 \
使用8进制常量的方式表达字符 : '\ddd' // d 是8进制数 '\123'
使用十六进制常量的方式表达字符: '\xdd' // d 是16进制数 '\x12'
整形常量表达方式有以下几种
二进制 八进制 十进制 十六进制
-
- 二进制 :逢二进一
0 1 10 11 100 101 110 111
标记 : **0b**
**0b**1 // 二进制的1
**0b**101110010111
-
- 八进制 :逢八进一
0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20
标记 : **0**
**0**1 // 八进制的1
**0**123456711244
-
- 十进制 :逢十进一
0 1 2 3 4 5 6 7 8 9 10
-
- 十六进制 :逢16进一
0 1 2 3 4 5 6 7 8 9 a b c d e f 10
标记 : **0x / 0X**
**0x**1 // 十六进制的1
**0x**15c4e4
2.变量
变量: 用来存储数据的空间 称为 变量
-
格式:
类型 变量名字; 类型: 决定空间大小和属性的 变量名字: 该空间的名字,使用该名字来代表该空间
-
ps:变量名字:(有要求)
-
1* 只能由 数字 字母(区分大小写) 下划线 组成 int a.out; // 这是错的 2* 不能以 数字开头 ,最好不要以下划线开头 int 1a; // 这是错的 3* 取名有意义 ; int age; int a; int userName; int user_name; 4* 不能使用关键字 : return int short long unsigned signed void ... 5* 名字不能太长,最好不要超过63
.
2 .1 _1 整型类型:
- 整型中的带符号的类型
short int ---> 简写为 short // 2个字节 16位
int int ---> 简写为 int // 4个字节 32位,c语言中可以2个或者4个
long int ---> 简写为 long // 4/8个字节 在32操作系统4个字节 在64位操作系统8个字节
long long int ---> 简写为 long long // 8个字节
以上类型 的最高位 是 符号位 : 0正数 1负数
short : 00000000 00000000
signed short ---> signed : 带符号的意思 ,默认 省略了
- 不带符号的: unsigned ,最高位不再是符号位,而是数据位
unsigned short
unsigned int
unsigned long
unsigned long long
2 .1 _2 浮点型 :
单精度 : float 4个字节
双精度 : double 8个字节
* 定义变量
float f; // 在内存中占用4个字节空间,该空间命名为f
double d,x,e;
* 赋值 :
float x;
x = 12.5;
* 存储:
float : 4个字节 32位
1个符号位 : 最高位 , 0正数 1负数
8个指数位 : 01111111 代表指数0
23小数位 : ....
例:
float f = 88.125;
88.125 :
88 : 1011000
0.125 : 0.001
88.125 —> 二进制: 1011000.001 -=-=–> 1.011000001 * 2^6
2 .1 _3 字符型
使用char 存储整型 :
signed char c = -10;
// 取值范围: -128 ~ 127 -128:00000000 ~ 127 : 01111111
unsigned char c = 20;
// 取值范围: 0~255 11111111
char c = ‘a’;
char c = 10;
// 内部存储Ascii码值
2 .1 _4 字符串
常量:
以 “ ”引起来的内容
“abc” ->本质为’a’ ‘b’ ‘c’ ‘\0’
变量
借助数组和指向字符的指针表示
例如:
借助数组表示
char str[10] = "hello"; // 定义一个长度为10的字符数组,存储字符串"hello"
借助指向指针表示
char *str = "hello"; // 定义一个指向字符的指针,指向字符串"hello"
ps:
需要注意,用字符数组表示的字符串需要预留足够的空间来存储字符串
而用指针表示的字符串则不需要,因为它们是指向已经存在的字符串常量的。
另外,字符串常量是不能被修改的,如果需要修改字符串,必须使用字符数组。
小结:
整型常量 : 二进制 八进制 十进制 十六进制
整型变量 : short int long long long unsigned
例如:
short s = 10;
short s = 0b1010;
short s = 012;
short s = 0xa;
二、进制及类型转换
1.进制间转换
-
十进制 和 二进制之间的转换 :
十进制 --》 二进制 : 除以进制数,逆向取余 例子: 10086 --》 0b10011101100110
练习:
10010 ----> 0b10011100011010二进制 --> 十进制 : 权位相加 0b10010 ---》 1*2^4 + 1*2^1 = 18
-
十进制 和 八进制 之间的转换:
十进制 --》 八进制 : 除以进制数,逆向取余 例子 : 10086 --》 023546 八进制 --> 十进制 : 权位相加 012300 --> 1*8^4 + 2*8^3 + 3*8^2
-
十进制 和 十六进制 之间的转换:
十进制 --》 十六进制 : 除以进制数,逆向取余 例子 : 10086 --》 0x2766 十六进制 --> 十进制 : 权位相加 0xabcde ---> 703710
小结:
十进制变任意进制: 除以进制数,逆向取余 。任意进制变十进制: 权位相加
利用位权相加,快速转换二进制、八进制、十六进制
-
二进制 和 八进制 之间的转换 :3 : 1
0b10010110101010100101111110 010 010 110 101 010 100 101 111 110 0 2 2 6 5 2 4 5 7 6
-
二进制 和 十六进制 之间的转换 :4 :1
0b10010110101010100101111110 0010 0101 1010 1010 1001 0111 1110 0x2 5 a a 9 7 e
-
八进制 和 十六进制 之间的转换 :
八进制 =====》 二进制 ====》 十六进制
小结:
二进制和八进制 :3 :1
二进制和十六进制: 4:1
八进制和十六进制: 转换位二进制 再做操作
2.数据的存储
这里需要引入补码的概念,通常数据以二进制补码形式存储在计算机中,为什么要这样呢?
我们换一个角度理解:
在进行算数运行时,计算机运算单元ALU只能进行简单的‘加’
而我们自己有四则运算。借助补码计算机也可以实现四则运算。
原码 : 程序员自己识别 分析的 码
反码 : 与原码符号位相同,其他位取反
补码 : 机器存储的码
正数:
原码 = 反码 = 补码
负数:
反码 => 原码 符号位不变,其他全部取反
补码 => 反码+1;
浮点型和整形存储稍稍不同:
【符号位】 【阶码位】 【尾数位】
篇幅有限具体见这篇博客:浮点型数据在内存中是如何存储的
3.类型转换
-
隐式转换
由低精度向高精度转变。 这是一个自发的过程
-
显式转换
由高精度向低精度转变,数据可能丢失。
-
特殊:
* 基本类型可以隐式的从高精度向低精度转变 ps: 正常情况下,显示转换应表示出来。
例子:
short s = 10; //在内存中占用2个字节空间,该空间命名为s
// 将 int 类型的 10 自动转为 short 类型 10 存入 s 中
//基本类型从小到大 :
char --> unsigned char --> short --> unsigned short
–> int --> unsigned int --> long --> unsigned long
–> long long --> unsigned long long --> float --> double
3.1 类型转换的规则 :
低于int类型的整型之间的运算,必须先自动转换为int再运算
char s = 10;
short sb = 20;
s + sb;
将s的值取出来放入cpu寄存器中,将该寄存器中值自动转换为int类型
将sb的值取出来放入cpu寄存器中,将该寄存器中值自动转换为int类型
寄存器中的两个 int 进行 加法运算,最后结果为 int 类型
- 同类型数据运算,得到同类型
long + long ---> long
5 / 10 ====> 0
- 有浮点型参与运算,转换为浮点型来运算:
char c = 25;
float f = 12.5;
f + c;
将c的值取出来放入cpu寄存器中,将该寄存器中值自动转换为float类型
将f的值取出来放入cpu寄存器中
寄存器中的两个 float 进行 加法运算,最后结果为 float 类型
- 断尾:
例子:
int i = 12.9;
// 将double类型的 12.9 断尾变成 int 类型的 12 存入 i中
总结
以上就是今天要讲的内容,稍微有点杂。数据类型主要是要分为常量和变量两类,内部按找整形、浮点、字符、字符串区分。其中浮点型的存储方式要理解一下,理解后可以尝试用整形的方式输出浮点型,计算出输出的大小能否对的上。 类型转换基本类型按照上面提示的几个转换规则,其他类型该强转的要显示转换,确保表达式两边类型时刻保持一致。
能力有限,若发现错误,欢迎交流指正。