零 ---- 千里之行,始于足下
壹 ---- 嵌入式C语言编程
在嵌入式的实际开发过程中我们更多的需要使用C语言进行编程,而在编程时我们需要处理各种类型的数据,C语言提供的数据类型到底有什么呢?又分别有什么不同呢?让我们通过这篇文章去了解吧。
C语言一共给我们提供了有如下几个数据类型:
数据类型 | 占用空间 |
short(短整型) | 2字节 |
int(整型) | 4字节 |
long(长整型) | 32位机器为4字节,64位机器为8字节 |
long long(长长整型) | 8字节 |
我们可以通过sizeof关键字来验证一下某个数据类型所占用的空间
printf("%d\n",sizeof(short));
printf("%d\n",sizeof(int));
printf("%d\n",sizeof(long));
printf("%d\n",sizeof(long long));
↑↑↑由于我的编译器是32位的,所以long显示为4字节↑↑↑
数据类型 |
占用空间 | 取值范围 |
short | 2字节 | -2^15~2^15-1(-32768到32767) |
int | 4字节 | -2^31~2^31-1(-2147483648到2147483647) |
long |
4字节 | -2^31~2^31-1(-2147483648到2147483647) |
unsigned short | 2字节 | 0~2^16-1(0到65535) |
unsigned int | 4字节 | 0~2^32-1(0到4294967295) |
unsigned long | 4字节 | 0~2^32-1(0到4294967295) |
这里简单提一下,数据类型的取值范围和该数据类型所占用的空间有关,一个字节等于8位,在未定义unsigned(无符号)时,默认将最高位用作符号标识位,0为正数、1为负数。
例如在有符号时,二进制 1000 0001 表示 -1 ,而在无符号时则是表示 129 。因此,在我们使用整型时,如果知道该整型不可能是负数时(如:人的岁数),我们通常会将其定义为无符号类型,以达到减少敲代码时出错的概率或者扩大存储的最大数取值范围。
可以看到一开始我将所有的整型类型都按照“%d”的格式打印,其实对于每个不同的数据类型,都有其特定是打印格式。在给数据赋值时也是如此,每个数据类型赋值也有其特定的方式,如下表所示:
整型常量 | 所代表数据类型 |
100 | 代表int类型 |
100l、100L | 代表long类型 |
100ll、100LL | 代表long long类型 |
100u、100U | 代表unsigned int类型 |
100ul、100UL | 代表unsigned long类型 |
100ull、100ULL | 代表unsigned long long类型 |
打印格式 | 含义 |
%hd | 输出short类型 |
%d | 输出int类型 |
%ld | 输出long类型 |
%lld | 输出long long类型 |
%hu | 输出unsigned short类型 |
%u | 输出unsigned int类型 |
%lu | 输出unsigned long类型 |
%llu | 输出unsigned long long类型 |
short _short = -32768;
int _int = -2147483647;
long _long = -2147483648l;
long long _long_long = -9223372036854775807ll;
unsigned short _ushort = 65535u;
unsigned int _uint = 4294967295u;
unsigned long _ulong = 4294967295ul;
unsigned long long _ulonglong = 18446744073709551615ull;
printf("short: %hd\n", _short);
printf("int: %d\n", _int);
printf("long: %ld\n", _long);
printf("longlong: %lld\n", _long_long);
printf("unsigned short: %hu\n", _ushort);
printf("unsigned int: %u\n", _uint);
printf("unsigned long: %lu\n", _ulong);
printf("unsigned long long: %llu\n", _ulonglong);
字符型用来存储一个单一字符,用 char 作为类型表示符。每个字符变量占用一个字节,用单引号(‘ ’)将字符赋值,使用%c输出,如下所示:
char _char = 'A';
char _ch = 65;
printf("_char: %c\n", _char);
printf("_ch: %c\n", _ch);
细心的同学可以发现,char类型也可以赋值整数,为什么呢?原来计算机只能识别0和1,并不能直接识别‘A’或者‘B’,但是在实际生活中,字符型的使用频率并不比整型少,那么怎么办呢?于是聪明的程序员将所有字符放到一个表里面,这个表被称为 ASCII 表,65就是表示字符'A',所以当 _ch 进行输出时,显示为‘A’。
ASCII值 | 控制字符 | ASCII值 | 字符 | ASCII值 | 字符 | ASCII值 | 字符 |
0 | NUT | 32 | (space) | 64 | @ | 96 | ` |
1 | SOH | 33 | ! | 65 | A | 97 | a |
2 | STX | 34 | " | 66 | B | 98 | b |
3 | ETX | 35 | # | 67 | C | 99 | c |
4 | EOT | 36 | $ | 68 | D | 100 | d |
5 | ENQ | 37 | % | 69 | E | 101 | e |
6 | ACK | 38 | & | 70 | F | 102 | f |
7 | BEL | 39 | ‘ | 71 | G | 103 | g |
8 | BS | 40 | ( | 72 | H | 104 | h |
9 | HT | 41 | ) | 73 | I | 105 | i |
10 | LF | 42 | * | 74 | J | 106 | j |
11 | VT | 43 | + | 75 | K | 107 | k |
12 | FF | 44 | , | 76 | L | 108 | l |
13 | CR | 45 | - | 77 | M | 109 | m |
14 | SO | 46 | . | 78 | N | 110 | n |
15 | SI | 47 | / | 79 | O | 111 | o |
16 | DLE | 48 | 0 | 80 | P | 112 | p |
17 | DC1 | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 | 50 | 2 | 82 | R | 114 | r |
19 | DC3 | 51 | 3 | 83 | S | 115 | s |
20 | DC4 | 52 | 4 | 84 | T | 116 | t |
21 | NAK | 53 | 5 | 85 | U | 117 | u |
22 | SYN | 54 | 6 | 86 | V | 118 | v |
23 | TB | 55 | 7 | 87 | W | 119 | w |
24 | CAN | 56 | 8 | 88 | X | 120 | x |
25 | EM | 57 | 9 | 89 | Y | 121 | y |
26 | SUB | 58 | : | 90 | Z | 122 | z |
27 | ESC | 59 | ; | 91 | [ | 123 | { |
28 | FS | 60 | < | 92 | \ | 124 | | |
29 | GS | 61 | = | 93 | ] | 125 | } |
30 | RS | 62 | > | 94 | ^ | 126 | ~ |
31 | US | 63 | ? | 95 | _ | 127 | DEL |
ASCII码大致由以下两部分组成:
----ASCII非打印控制字符:ASCII表上数字0-31分配给了控制字符,用于控制打印机等一些外围设备。
----ASCII打印字符:数字32-126分配给了能在键盘上找到的字符,当查看或打印文档时就会出现。数字127代表DEL命令。
浮点型是专门用于存储小数的数据类型。在C语言中,浮点型分为单精度浮点型(float)和双精度浮点型(double),两者的区别是双精度浮点型比单精度浮点型的精度更加高。float在计算机中存储占用4字节,32位,有效位数为7位(6位小数+小数点),而双精度(double)在计算机中存储占用8字节,64位,有效位数为16位(15位小数+小数点)。
单精度浮点型小数通常用 f 结尾表示,没有使用 f 结尾的小数通常表示双精度浮点型。在输出时,分别使用 %f 和 %lf 表示。以下举例:
//传统的赋值方式
float _float = 3.14f;
double _double = 3.14;
printf("_float = %f\n",_float);
printf("_double = %lf\n",_double);
//科学计数法赋值
_float = 1.1e3f; //1.1*10^3 e可以写成为E
printf("_float = %f\n",_float);
_float = 1.2E-3f; //1.2*10^-3
printf("_float = %f\n",_float);
在日常生活当中,我们通常会接触到保留m位小数这样的例子,那么在实际输出中,我们可以通过 %n.mf 的方式去表达,%n.mf表示输出n个有效位(包含小数点本身的1位),其中小数点保留m位。
例如我们将3.1415926通过 %6.4f 的方式输出,则输出结果为3.1416。被舍弃的有效位将会被四舍五入。
由于浮点型变量是由有限的存储单元组成的,因此只能提供有限的有效数字。在有效数字以外的数字将被舍去,这样可能会产生一些误差。我们大胆假设给float赋一个超过7位有效数字的值,并且通过查看float的小数点后八位会是样什么的结果。
float _float = 3.141592653589793f;
printf("_float : %f\n", _float);
printf("_float : %.8f\n", _float);
首先,当我们正常输出超过有效数据位的时候,数据会被截断,且进行四舍五入。当我们查看小数点后八位的时候,发现有效数据仍然有效,但超过有效数据会发生误差。因此,我们在给浮点型赋值的时候,必须要使用合理的精度,通常可以无脑使用double作为小数的数据类型。
1、如何快速将字符的大写字母转换成小写字母? 例如: ’A‘—>'a'
2、如何快速将整型转换成字符型? 例如:8—>'8'
3、已知浮点型有误差,那么要如何比较浮点型之间是否相等呢?