- 基本定义:它们各自是什么?
- 内存大小和取值范围:它们在内存中占多少空间?能表示多大的数?
- 精度问题:这是它们最核心的区别。
- 使用场景:什么时候用哪个?
- 代码示例:直观感受它们的区别。
- 总结与最佳实践。
基本定义
在 C 语言中,数据类型是告诉编译器这个变量是什么类型的数据,需要分配多少内存空间,以及可以对这个变量进行哪些操作。

-
int(Integer - 整数)- 用途:用于存储没有小数部分的数字,也就是整数。
10,-50,0,32767。 - 本质:它表示的是一个精确的、完整的数值。
- 用途:用于存储没有小数部分的数字,也就是整数。
-
float(Single-precision floating-point number - 单精度浮点数)- 用途:用于存储带有小数部分的数字,即实数。
14,-0.001,0。 - 本质:它用科学计数法(
尾数 x 指数)的形式在计算机内存中存储一个近似值,关键词是“近似”和“单精度”。
- 用途:用于存储带有小数部分的数字,即实数。
-
double(Double-precision floating-point number - 双精度浮点数)- 用途:与
float相同,用于存储实数。 - 本质:可以看作是
float的“增强版”,它使用更多的内存空间来存储科学计数法的尾数和指数,因此能提供更高精度和更大范围的近似值,关键词是“更高精度”和“双精度”。
- 用途:与
内存大小和取值范围
数据类型的大小和范围取决于你的操作系统和编译器(通常是 32 位或 64 位),但有一个广泛接受的标准。

| 数据类型 | 关键字 | 大小 (字节) | 典型范围 | 说明 |
|---|---|---|---|---|
| 整数 | int |
4 | -2,147,483,648 到 2,147,483,647 | 用于精确的整数计算。 |
| 单精度浮点数 | float |
4 | 约 ±3.4E-38 到 ±3.4E+38 | 精度较低,约 6-7 位有效数字。 |
| 双精度浮点数 | double |
8 | 约 ±1.7E-308 到 ±1.7E+308 | 精度较高,约 15-16 位有效数字。 |
重要提示:
sizeof操作符可以用来在你的特定环境下查看类型的大小:printf("%zu", sizeof(int));。float和double的范围非常大,但这是以牺牲精度为代价的,它们能表示一个极大的数,但不一定能精确表示这个数。
精度问题(核心区别)
这是 int、float、double 之间最根本、最重要的区别。
int 的精度:绝对精确
int 存储的是整数,所以只要在它的表示范围内,它永远是精确的。int a = 123456789; 这个值在内存中就是精确的 123456789。
float 和 double 的精度:近似值
计算机使用二进制来表示小数,就像我们用十进制表示小数一样,但很多十进制小数在二进制中是无限循环小数,无法被精确表示。

示例 1:经典的 0.1 问题
#include <stdio.h>
int main() {
float f = 0.1f; // 注意 f 后缀,表示这是一个 float 常量
double d = 0.1;
printf("float f = 0.1 的实际值: %.15f\n", f);
printf("double d = 0.1 的实际值: %.15f\n", d);
return 0;
}
可能的输出:
float f = 0.1 的实际值: 0.100000001490116
double d = 0.1 的实际值: 0.100000000000000
float(0.100000001490116):可以看到,float只能精确到小数点后 6-7 位,后面的000001490116是计算误差。double(0.100000000000000):double的精度高得多,在这个例子中,它精确地表示了 0.1(至少在小数点后15位内是精确的)。
示例 2:有效数字位数
有效数字是指一个数从第一个非零数字开始,到最后一个数字为止的所有数字。
#include <stdio.h>
int main() {
float f_num = 1234567.89; // 8位有效数字
double d_num = 1234567.89;
printf("float 的值: %.8f\n", f_num);
printf("double 的值: %.8f\n", d_num);
return 0;
}
可能的输出:
float 的值: 1234567.87500000 // 精确到小数点后2位,但整数部分末尾的 .89 变成了 .875
double 的值: 1234567.89000000 // 保持了更高的精度
这个例子说明,当数字的有效数字超过 float 的能力(约6-7位)时,它就会开始丢失精度,而 double 可以轻松处理15-16位的有效数字。
使用场景(如何选择)
什么时候用 int?
当你处理的数值一定是整数,且不能有误差时,必须使用 int。
- 计数器:
for (int i = 0; i < 100; i++) - 数组索引:
my_array[5] - 人的年龄、数量、ID 等等。
什么时候用 float?
当你对内存占用非常敏感,且对精度的要求不高时。
- 在嵌入式系统或移动设备上,内存资源有限。
- 游戏开发中,对性能要求极高,可以接受一些视觉上的误差(如某些粒子效果)。
- 图形学中,如果精度要求不是那么苛刻。
float是用内存换性能。
什么时候用 float 或 double?
只要你处理的数值可能包含小数,就应该使用浮点数,在这种情况下,默认首选 double。
- 科学计算
- 金融计算(注意:金融计算对精度要求极高,
double有时也不够,通常需要使用专门的十进制库) - 物理模拟
- 任何需要表示测量值(如长度、重量、时间)的场景。
为什么默认用 double?
在现代计算机上,float 和 double 的计算速度差异已经非常小,甚至在某些架构上 double 更快,而 double 提供的精度远超 float,能避免绝大多数因精度不足导致的 bug,除非你有特殊原因(如内存限制),否则请直接使用 double。
代码示例
这个例子展示了不同类型在计算和存储时的差异。
#include <stdio.h>
int main() {
// --- 1. 常量后缀 ---
// 整数默认是 int
// 浮点数默认是 double
// f 或 F 后缀表示 float
// l 或 L 后缀表示 long (整数) 或 long double (浮点数)
int a = 10;
float b = 3.14f; // 明确表示这是一个 float
double c = 3.14159265358979; // 默认是 double
// --- 2. 打印格式说明符 ---
// %d - int
// %f - float/double (默认保留6位小数)
// %.15f - float/double (自定义保留15位小数,用于观察精度)
// %lf - 用于 scanf 读取 double
// %f - 用于 scanf 读取 float (也可以用 %lf,但 %f 更标准)
printf("a (int) = %d\n", a);
printf("b (float) = %.15f\n", b);
printf("c (double) = %.15f
