程序本质上是对数据的加工。C 语言要求每个数据都有明确的类型——是整数、小数还是字符,决定了它占多少内存、能存多大范围。本文系统梳理 C 的基本数据类型与变量规则,为后续学习打下坚实基础。
1. 基本数据类型一览
C 的基本类型可以概括为"四大家族":
| 类型 | 说明 | 典型大小 | 格式符 |
|---|---|---|---|
| char | 字符 / 小整数 | 1 字节 | %c |
| int | 整数 | 4 字节 | %d |
| float | 单精度浮点 | 4 字节 | %f |
| double | 双精度浮点 | 8 字节 | %lf |
注意:字节数在不同平台上可能不同,sizeof 运算符可以随时查询。
2. 变量声明与初始化
C 是静态类型语言,变量"先声明,后使用"。声明格式为 类型 变量名;:
#include <stdio.h>
int main(void) {
int age = 18; // 声明并初始化
float price = 3.99f; // 浮点字面量加 f 后缀
double pi = 3.14159265358979;
char grade = 'A'; // 字符用单引号
printf("age=%d, price=%.2f, pi=%.15f, grade=%c\n",
age, price, pi, grade);
return 0;
}
变量名只能含字母、数字、下划线,不能以数字开头,也不能与 C 的关键字(int、return 等)重名。
3. 整型家族与取值范围
在 int 前加 short、long 或 unsigned 修饰,可以得到不同范围、不同语义的整型。用 limits.h 里的宏可以查询边界:
#include <stdio.h>
#include <limits.h>
int main(void) {
printf("int 范围: %d ~ %d\n", INT_MIN, INT_MAX);
printf("long long 范围: %lld ~ %lld\n", LLONG_MIN, LLONG_MAX);
printf("unsigned int 最大: %u\n", UINT_MAX);
printf("char 大小: %zu 字节\n", sizeof(char));
return 0;
}
容易踩的坑:整数溢出:结果超出类型范围会"回绕"到另一头,且不报错——大计数请用 long long。
4. 浮点型与精度陷阱
浮点数在计算机中按 IEEE 754 标准存储,无法精确表示所有小数。比如 0.1 + 0.2 并不严格等于 0.3:
#include <stdio.h>
int main(void) {
double sum = 0.1 + 0.2;
printf("0.1 + 0.2 = %.20f\n", sum); // 0.30000000000000004441
if (sum == 0.3) {
printf("相等\n");
} else {
printf("不相等!比较浮点数要用差值判断\n");
}
return 0;
}
比较浮点数时,应判断两者之差是否小于一个极小值(如 1e-9),而不是直接用 ==。
5. 常量与类型转换
用 const 修饰的变量不可修改;用 #define 定义的宏在预处理阶段直接替换文本:
#include <stdio.h>
#define PI 3.14159
int main(void) {
const int DAYS = 7;
// DAYS = 8; // 错误:const 不可修改
double r = 2.0;
double area = PI * r * r; // 隐式转换
int n = (int)area; // 显式转换:截断小数
printf("面积=%.2f, 取整后=%d\n", area, n);
return 0;
}
隐式转换遵循"向精度高的方向转";显式转换用 (类型) 强制指定,但可能丢失精度或数据。
6. 字符类型与 ASCII
char 本质上是 1 字节整数,字符 'A' 就是数字 65,可以直接参与算术运算:
#include <stdio.h>
int main(void) {
char c = 'A';
printf("'A' 的 ASCII 码: %d\n", c); // 65
printf("小写: %c\n", c + 32); // 'a'
return 0;
}
💡 学习建议:动手写一个小程序,把每种类型都声明一遍并用 printf 打印,再用 sizeof 观察它们占多少字节——亲手验证过的知识才记得牢。