1 数据类型分类
数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。数据类型决定了存储占用的空间,以及如何解释存储的位模式。
C语言的数据类型分为以下几类:
- 基本数据类型:整数类型、字符类型、浮点数类型和布尔类型。
- 枚举类型:本质上也是算术类型,被用来定义在程序中只能赋予其一定的离散整数值的变量。
- void 类型:表示没有值的数据类型,通常用于函数返回值。
- 聚合类型:数组类型、指针类型和结构体类型。
2 基本数据类型
2.1 整数数据类型
数据类型 | 字节数 | 格式符 | 数据范围 | 最小值宏 | 最大值宏 |
short(短整型) | 2 | %hd | -215 ~ 215-1 (-32768 ~ 32767) | SHRT_MIN | SHRT_MAX |
int(整型) | 4 | %d | -231 ~ 231-1 (-2147483648 ~ 2147483647) | INT_MIN | INT_MAX |
long(长整型) | 4 | %ld | -231 ~ 231-1 (-2147483648 ~ 2147483647) | LONG_MIN | LONG_MAX |
long long(长长整型) | 8 | %lld | -263 ~ 263-1 | LLONG_MIN | LLONG_MAX |
unsigned short(无符号 短整型) | 同 short | %hu | 0 ~ 216-1 (0 ~ 65535) | 0 | USHRT_MAX |
unsigned int(无符号 整型) | 同 int | %u | 0 ~ 232-1 (0 ~ 4294967295) | 0 | UINT_MAX |
unsigned long(无符号 长整型) | 同 long | %lu | 0 ~ 232-1 (0 ~ 4294967295) | 0 | ULONG_MAX |
unsigned long long(无符号 长长整型) | 同 long long | %llu | 0 ~ 264-1 | 0 | ULLONG_MAX |
由于C 标准没有具体规定以上各类数据所占用的字节数。因此,在不同系统、编译器下,数据类型占用的字节数会有所不同。例如,long 类型,相同的 gcc 编译器下,在 Windows 系统中占 4 字节,而在 Linux 系统中占 8 字节。
为了得到某个类型或某个变量在特定平台上的准确大小,可以使用 sizeof 运算符,语法格式包括以下两种方式:
- sizeof(数据类型):
/*
sizeof(int) 直接打印int类型占用内存大小。
查看sizeof 返回的占用内存大小,需要使用 %lu 格式符
*/
printf("%lu\n", sizeof(int));
- sizeof(变量名):
int var = 100;
/*
sizeof(var) 直接打印var 变量占用内存大小。
查看sizeof 返回的占用内存大小,需要使用 %lu 格式符
*/
printf("%lu\n", sizeof(var));
可以使用 sizeof 查看 整数类型占用内存的大小,代码示例:
#include <stdio.h>
int main(void)
{
// 查看short内存占用
printf("short占用内存大小 = %lu\n", sizeof(short));
// 查看int内存占用
printf("int占用内存大小 = %lu\n", sizeof(int));
// 查看long内存占用
printf("long占用内存大小 = %lu\n", sizeof(long));
// 查看long long内存占用
printf("long long占用内存大小 = %lu\n", sizeof(long long));
return 0;
}
可以引入头文件 #include <limits.h> 借助宏来查看 数据类型在当前平台上 对应的最小、最大值,代码示例:
#include <stdio.h>
#include <limits.h>
int main(void)
{
// 查看short类型最大最小值
printf("short 最小值 = %hd, 最大值 = %hd\n", SHRT_MIN, SHRT_MAX);
printf("unsigned short 最小值 = 0 最大值 = %hu\n", USHRT_MAX);
// 查看int类型最大最小值
printf("int 最小值 = %d,最大值 = %d\n", INT_MIN, INT_MAX);
printf("unsigned int 最小值 = 0, 最大值 = %u\n", UINT_MAX);
// 查看long类型最大最小值
printf("long 最小值 = %ld, 最大值 = %ld\n", LONG_MIN, LONG_MAX);
printf("unsigned long 最小值 = 0 最大值 = %lu\n", ULONG_MAX);
// 查看long long类型最大最小值
printf("long long 最小值 = %lld, 最大值 = %lld\n", LLONG_MIN, LLONG_MAX);
printf("unsigned long long 最小值 = 0, 最大值 = %llu\n", ULLONG_MAX);
return 0;
}
2.2 浮点类型
在计算机内部以浮点方式表示(小数点是浮动的),因此也叫浮点型。浮点类型包括:
- float (单精度)
- double (双精度)
其中,实型数据没有八、十六进制,也没有 unsigned 无符号形式。在计算机底层采用的是近似计算,实现比较复杂,且不同平台处理方式不同。下表列出了关于标准浮点类型的存储大小、值范围和精度的细节:
类型 | 字节数 | 格式符 | 有效数字 | 常量后缀 |
float (单精度) | 4 | %f | 6~7 | f |
double (双精度) | 8 | %lf | 15~16 | 无 |
系统默认看做 double 类型。如想指明为 float 类型,需加后缀 f,3.14f。
关于浮点类型有效数字需要注意以下几点:
- 有效数字6~7:
- 整数部分 + 小数部分 <= 6 位, 准确。
- 整数部分 + 小数部分 == 7 位,可能准确,也可能不准确。
- 整数部分 + 小数部分 > 7位。大多不准确。
- 有效数字15~16:
- 整数部分 + 小数部分 <= 15 位, 准确。
- 整数部分 + 小数部分 == 16 位,可能准确,也可能不准确
- 整数部分 + 小数部分 > 16位。大多不准确。
显示小数时,%f 和 %lf 默认保留 6 位小数。
如需指定小数位数,使用格式符 %.nf ,n 为几,表示精确到小数点后几位,会对 n+1 位做 4 舍 5 入。代码示例:
#include <stdio.h>
int main(void)
{
// 定义20位小数的float变量pi
float pi1 = 3.14159265358979323846f;
// 定义20 位小数的double变量pi
double pi2 = 3.14159265358979323846;
printf("f=%.20f\n", pi1);
printf("d=%.20lf\n", pi2);
return 0;
}
2.3 字符类型
C语言定义 char 类型来表示字符数据。 其本质依然是存储数值,因此与数值型类似,也有有符号、无符号之分。占用 1 个字节内存大小。
类型 | 字节数 | 格式符 | 数据范围 | 最小值宏 | 最大值宏 |
char | 1 | %hhd | -27 ~ 27-1 (-128 ~ 127) | CHAR_MIN | CHAR_MAX |
unsigned char | 1 | %hhu | 0~28-1 (0 ~ 255) | 0 | UCHAR_MAX |
2.3.1 ASCII 码
char 类型在程序中,最常用来表示字符。其本质依然是一个数字,但每个值都对应一个固定的字符,共定义了128个字符。称之为 ASCII 码 (American Standard Code for Information Interchange) 美国信息交换标准代码。
ASCII值 | 控制字符 | ASCII值 | 字符 | ASCII值 | 字符 | ASCII值 | 字符 |
0 | NUL | 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 | DCI | 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 |
注意:我们从键盘键入的所有内容都是字符。如,键入数字 1,实际是字符 ‘1’,真正存储在计算机内的是 49(字符 1 的 ASCII 码值),而如果我们键入了 35,实际上这是两个字符。真正存储在计算机内的是 51 和 53(字符 3 和 字符 5 的 ASCII 码值)。我们可以用 printf 结合 格式符 %c,显示字符。 如果用 %d,就显示 其 ASCII 值了。代码示例:
#include <stdio.h>
int main(void)
{
char ch = 53;
printf("ASCII为:%d, 字符为:%c\n", ch, ch);
return 0;
}
2.3.4 转义字符
C 语言提供了一类特殊的字符,是由 \ 和特定字符组合而成,称之为 转义字符。它们都是一个字符,如:
- ‘\n’ 这是 1 个字符。 代表 回车换行(回车键)。
- ‘\t’ 也是 1 个字符。代表 制表符 (Tab键)。
- ‘\b’ 同样是 1 个字符。 代表 退格符(Backspace 键)。
- ‘\0’ 是一个字符。代表 空。对应 ASCII 值 0。
- ‘\ddd’ 是一个字符。ddd 对应 3 个八进制数(没有用 0 开头)。 如:\141 对应 ASCII 值为 97,代表 ‘a’。
- ‘\xhh’ 是一个字符。x 表十六进制,hh 对应 2 个十六进制数。 如:\x41 对应 ASCII 值为 65,代表 ‘A’。
\ 还可以在特定环境下,将一个字符还原其本身意。比如,现在想在 printf(“%d\n”,10);输出 10 的时候,用 “” 把 10 包裹住。 如果直接写printf(“ “%d” \n”,10);是会报错的。这时,可以使用 \" 将 “ 进行转义,还原其本身意。
printf("\"%d\"", 10); // 这里的 \" 看做一个双引号字符。
类似的还有:
- \' 代表 单引号。
- \\ 代表 反斜杠。
2.4 布尔类型
C语言在设计之初是没有真正意义上的布尔类型的,使用 1 和 0,对应表示真、假。但是,其他编程语言像 C++、java 都设计有布尔数类型。 C语言在1999 年推出的新标准(C99)中,也加入了 布尔类型。用 true 来代表 1,为真;用 false 来代表 0,为假。使用时,需要引入头文件 #include <stdbool.h>
#include <stdbool.h>
int main(void)
{
printf("%d, %d\n", true, false);
return 0;
}
虽然语法上与其他语言一致,但 C 语言每次在使用时需先引入头文件,较为麻烦。 因此,一些工程师还是喜欢直接在程序中用 1 和 0 来表示 真和假。
3 基本类型转换
基本类型转换是将一个数据类型的值转换为另一种数据类型的值。C 语言中有两种类型转换:
- 隐式类型转换:隐式类型转换是在表达式中自动发生的,无需进行任何明确的指令或函数调用。它通常是将一种较小的类型自动转换为较大的类型,例如,将int类型转换为long类型或float类型转换为double类型。隐式类型转换也可能会导致数据精度丢失或数据截断。
int i = 10;
float f = 3.14;
double d = i + f; // 隐式将int类型转换为double类型
- 显式类型转换:显式类型转换需要使用强制类型转换运算符(type casting operator),它可以将一个数据类型的值强制转换为另一种数据类型的值。强制类型转换可以使程序员在必要时对数据类型进行更精确的控制,但也可能会导致数据丢失或截断。
double d = 3.14159;
int i = (int)d; // 显式将double类型转换为int类型
---E N D---
喜欢的记得关注哦!
您的支持是我们前进的动力!