第 4 天:C 语言核心数据类型 —— 整型、浮点型、字符型的定义与运用

目录
前言:
在上一篇学习中,我们编写了第一个 C 程序 "Hello World",了解了 C 程序的基本结构:包含头文件、定义主函数、使用输入输出函数以及程序执行的基本流程。同时,我们也学习了代码规范和良好的编程习惯,为后续的 C 语言学习奠定了基础。
今天,我们将深入探讨 C 语言的核心基础 —— 数据类型。计算机程序的本质是处理数据,而数据类型决定了数据的存储方式、取值范围和可执行的操作。掌握基本数据类型的使用,是编写任何有实际意义程序的前提。
一、数据类型的基本概念
在编程中,数据类型是对数据的分类,它告诉编译器:
- 该数据在内存中占用多少存储空间
- 该数据可以进行哪些操作(如加减乘除、比较等)
- 数据在内存中的存储格式
想象一下,如果现实世界中没有对事物的分类(如动物、植物、交通工具),我们将很难描述和处理它们。同样,在 C 语言中,没有数据类型,计算机就无法正确理解和处理我们提供的数据。
C 语言是一种 "强类型" 语言,这意味着:
- 每个变量必须先定义类型,才能使用
- 不同类型的数据进行操作时需要显式转换
- 编译器会检查数据类型的使用是否正确
二、整型:处理整数的类型
整型(integer)用于存储没有小数部分的数字,如 10、-3、0 等。C 语言提供了多种整型,它们的区别主要在于占用内存大小和表示范围。
2.1 整型的分类
C 语言中的整型家族包括:
| 类型关键字 | 含义 | 典型占用空间 | 表示范围(有符号) |
|---|---|---|---|
| int | 基本整型 | 4 字节 | -2,147,483,648 到 2,147,483,647 |
| short(short int) | 短整型 | 2 字节 | -32,768 到 32,767 |
| long(long int) | 长整型 | 4 字节(32 位系统)8 字节(64 位系统) | 至少与 int 范围相同 |
| long long(long long int) | 双长整型 | 8 字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
此外,在这些类型前加上unsigned关键字,可以得到无符号整型,只能表示非负整数:
| 无符号类型 | 典型占用空间 | 表示范围 |
|---|---|---|
| unsigned int | 4 字节 | 0 到 4,294,967,295 |
| unsigned short | 2 字节 | 0 到 65,535 |
| unsigned long | 4/8 字节 | 0 到 4294967295/18446744073709551615 |
| unsigned long long | 8 字节 | 0 到 18,446,744,073,709,551,615 |
注意:C 标准只规定了各种类型的最小范围,具体大小可能因编译器和操作系统而异。
2.2 整型变量的定义与使用
定义整型变量的语法:
c
运行
类型关键字 变量名;
初始化(定义时赋值):
c
运行
类型关键字 变量名 = 初始值;
示例代码:
c
运行
#include
int main() {
// 定义各种整型变量
int age; // 定义int类型变量,未初始化
short score; // 定义short类型变量
long population; // 定义long类型变量
// 定义并初始化变量
int student_count = 45; // 初始化int变量
unsigned int positive_num = 100; // 无符号int变量
short temperature = -5; // 负数初始化
long long big_number = 123456789012345LL; // 长整数需加LL后缀
// 输出变量值
printf("学生数量: %d\n", student_count);
printf("正数: %u\n", positive_num); // 无符号int用%u输出
printf("温度: %hd\n", temperature); // short用%hd输出
printf("大数字: %lld\n", big_number); // long long用%lld输出
// 变量赋值
age = 20;
printf("年龄: %d\n", age);
// 变量修改
age = age + 5; // 年龄增加5
printf("五年后年龄: %d\n", age);
return 0;
}
输出结果:
plaintext
学生数量: 45
正数: 100
温度: -5
大数字: 123456789012345
年龄: 20
五年后年龄: 25
代码解释:
- 不同整型有不同的输出格式符:
%d(int)、%hd(short)、%ld(long)、%lld(long long)、%u(unsigned int) - 非常大的整数常量需要加后缀:
L表示 long,LL表示 long long - 变量可以先定义后赋值,也可以在定义时直接初始化
2.3 整型溢出问题
每种整型都有固定的表示范围,当赋值或计算结果超出这个范围时,就会发生溢出。溢出是 C 语言中常见的错误来源。
溢出示例代码:
c
运行
#include
#include // 包含整数类型范围定义
int main() {
// 打印int类型的最大值和最小值
printf("int类型范围: %d 到 %d\n", INT_MIN, INT_MAX);
// 演示溢出
int max_int = INT_MAX;
int overflow1 = max_int + 1; // 上溢
printf("INT_MAX + 1 = %d\n", overflow1);
int min_int = INT_MIN;
int overflow2 = min_int - 1; // 下溢
printf("INT_MIN - 1 = %d\n", overflow2);
// 无符号整型溢出
unsigned int max_uint = UINT_MAX;
unsigned int u_overflow = max_uint + 1;
printf("UINT_MAX + 1 = %u\n", u_overflow);
return 0;
}
输出结果:
plaintext
int类型范围: -2147483648 到 2147483647
INT_MAX + 1 = -2147483648
INT_MIN - 1 = 2147483647
UINT_MAX + 1 = 0
代码解释:
limits.h头文件定义了各种整型的最值宏,如INT_MAX、INT_MIN- 有符号整型溢出会导致数值 "环绕",这是一种未定义行为,结果可能不符合预期
- 无符号整型溢出会按模运算处理(如最大值加 1 变为 0)
避免溢出的方法:
- 根据实际需求选择合适大小的整型
- 进行可能溢出的计算前,先检查边界条件
- 关键计算使用更大范围的类型
三、浮点型:处理小数的类型
浮点型(floating-point)用于存储带小数部分的数字,如 3.14、-0.001、2.0 等。
3.1 浮点型的分类
C 语言中的浮点型包括:
| 类型关键字 | 含义 | 典型占用空间 | 有效数字位数 | 表示范围(绝对值) |
|---|---|---|---|---|
| float | 单精度浮点型 | 4 字节 | 6-7 位 | 1.175494e-38 到 3.402823e+38 |
| double | 双精度浮点型 | 8 字节 | 15-17 位 | 2.225074e-308 到 1.797693e+308 |
| long double | 长双精度浮点型 | 8/10/16 字节 | 18-19 位 | 更大范围 |
注意:double 类型的精度和范围都比 float 大,在实际编程中更常用。
3.2 浮点型变量的定义与使用
示例代码:
c
运行
#include
#include // 包含浮点型范围定义
int main() {
// 定义浮点型变量
float pi_float;
double pi_double;
long double pi_long_double;
// 初始化变量
pi_float = 3.14159f; // float常量需加f或F后缀
pi_double = 3.1415926535; // 默认为double类型
pi_long_double = 3.14159265358979323846L; // long double需加l或L后缀
// 输出变量值
printf("float类型的pi: %.6f\n", pi_float); // 保留6位小数
printf("double类型的pi: %.10lf\n", pi_double); // 保留10位小数
printf("long double类型的pi: %.15Lf\n", pi_long_double); // 保留15位小数
// 打印浮点型的范围和精度
printf("\nfloat类型最小值: %e\n", FLT_MIN); // 科学计数法输出
printf("float类型最大值: %e\n", FLT_MAX);
printf("float有效数字位数: %d\n", FLT_DIG);
printf("\ndouble类型最小值: %e\n", DBL_MIN);
printf("double类型最大值: %e\n", DBL_MAX);
printf("double有效数字位数: %d\n", DBL_DIG);
return 0;
}
输出结果:
plaintext
float类型的pi: 3.141590
double类型的pi: 3.1415926535
long double类型的pi: 3.141592653589793
float类型最小值: 1.175494e-38
float类型最大值: 3.402823e+38
float有效数字位数: 6
double类型最小值: 2.225074e-308
double类型最大值: 1.797693e+308
double有效数字位数: 15
代码解释:
- 浮点型的输出格式符:
%f(float)、%lf(double)、%Lf(long double) %.6f表示保留 6 位小数输出- 科学计数法输出使用
%e格式符 - float 常量后需加
f或F,否则默认为 double 类型 float.h头文件定义了浮点型的范围和精度宏
3.3 浮点型的精度问题
浮点型变量在存储时可能存在精度损失,这是由于二进制无法精确表示某些十进制小数。
精度问题示例:
c
运行
#include
int main() {
float a = 0.1f;
float b = 0.2f;
float c = a + b;
printf("0.1 + 0.2 = %f\n", c);
printf("0.1 + 0.2 == 0.3? %s\n", (c == 0.3f) ? "是" : "否");
// 正确的比较方式
float epsilon = 1e-6f; // 误差范围
if (c - 0.3f < epsilon && 0.3f - c < epsilon) {
printf("使用误差范围比较: 0.1 + 0.2 约等于 0.3\n");
}
return 0;
}
输出结果:
plaintext
0.1 + 0.2 = 0.300000
0.1 + 0.2 == 0.3? 否
使用误差范围比较: 0.1 + 0.2 约等于 0.3
代码解释:
- 由于精度限制,0.1 + 0.2 的结果并不精确等于 0.3
- 比较浮点型变量时,不应使用
==直接比较,而应检查它们的差值是否小于一个很小的误差范围(如 1e-6)
四、字符型:处理单个字符
字符型(char)用于存储单个字符,如 'a'、'5'、'+' 等。在 C 语言中,字符型实际上是一种特殊的整型。
4.1 字符型变量的定义与使用
示例代码:
c
运行
#include
int main() {
// 定义字符变量
char letter;
char digit;
char symbol;
// 初始化字符变量(使用单引号)
letter = 'A';
digit = '5';
symbol = '#';
// 输出字符及其ASCII值
printf("字符: %c, ASCII值: %d\n", letter, letter);
printf("字符: %c, ASCII值: %d\n", digit, digit);
printf("字符: %c, ASCII值: %d\n", symbol, symbol);
// 字符型本质是整型,可以进行算术运算
char next_letter = letter + 1; // 'A' + 1 = 'B'
printf("下一个字母: %c\n", next_letter);
// 直接使用ASCII值赋值
char heart = 10084; // 10084是心形符号的Unicode值
printf("特殊符号: %c\n", heart);
return 0;
}
输出结果:
plaintext
字符: A, ASCII值: 65
字符: 5, ASCII值: 53
字符: #, ASCII值: 35
下一个字母: B
特殊符号: ❤
代码解释:
- 字符型变量用
char关键字定义,字符常量用单引号'括起来 %c格式符用于输出字符,%d格式符用于输出字符的 ASCII 值- 在 C 语言中,字符型本质上是 8 位整型,可以进行算术运算
- 字符在内存中存储的是其对应的 ASCII 值(或扩展编码值)
4.2 转义字符
转义字符是一种特殊的字符常量,以反斜杠\开头,用于表示那些无法直接输入的字符。
常用转义字符示例:
c
运行
#include
int main() {
printf("转义字符示例:\n");
printf("换行符 \\n: 第一行\n第二行\n");
printf("制表符 \\t: 姓名\t年龄\t性别\n");
printf("双引号 \\\": 他说\"你好\"\n");
printf("单引号 \\\': 这是一个单引号'\n");
printf("反斜杠 \\\\: 路径为C:\\Users\\Documents\n");
printf("回车符 \\r: abcdef\\r123 -> ");
printf("abcdef\r123\n"); // \r会将光标移到行首
return 0;
}
输出结果:
plaintext
转义字符示例:
换行符 \n: 第一行
第二行
制表符 \t: 姓名 年龄 性别
双引号 \": 他说"你好"
单引号 \': 这是一个单引号'
反斜杠 \\: 路径为C:\Users\Documents
回车符 \r: abcdef\r123 -> 123def
常用转义字符表:
| 转义字符 | 含义 | ASCII 值(十进制) |
|---|---|---|
| \n | 换行符 | 10 |
| \t | 水平制表符(Tab) | 9 |
| \r | 回车符 | 13 |
| \a | 警报(响铃) | 7 |
| \b | 退格符 | 8 |
| \f | 换页符 | 12 |
| \v | 垂直制表符 | 11 |
| " | 双引号 | 34 |
| ' | 单引号 | 39 |
| \ | 反斜杠 | 92 |
| \ddd | 1-3 位八进制数表示的字符 | - |
| \xhh | 1-2 位十六进制数表示的字符 | - |
五、数据类型的选择与应用场景
选择合适的数据类型对程序的正确性、效率和可读性至关重要。
5.1 数据类型选择原则
- 够用就好:选择能满足需求的最小类型,节省内存空间
- 考虑范围:确保数据不会超出所选类型的表示范围
- 精度需求:处理小数时,根据精度要求选择 float 或 double
- 兼容性:考虑不同平台之间的数据类型兼容性
5.2 常见应用场景
| 数据类型 | 典型应用场景 |
|---|---|
| int | 大多数整数场景(年龄、数量、索引等) |
| short | 存储较小范围的整数(温度、分数等) |
| long long | 存储大整数(身份证号、电话号码、时间戳等) |
| unsigned int | 存储非负整数(长度、数量、计数等) |
| float | 对精度要求不高的小数(如身高、体重等) |
| double | 对精度要求高的计算(科学计算、金融数据等) |
| char | 存储单个字符、ASCII 码、小范围整数 |
5.3 综合示例:个人信息管理
c
运行
#include
int main() {
// 定义不同类型的变量存储个人信息
char first_initial = 'J'; // 名的首字母
char last_name[] = "Smith"; // 姓(字符串)
int age = 30; // 年龄
unsigned int height_cm = 175; // 身高(厘米)
float weight_kg = 72.5f; // 体重(千克)
double salary = 5896.75; // 月薪
unsigned long long phone = 13812345678ULL; // 电话号码
// 输出个人信息
printf("===== 个人信息 =====\n");
printf("姓名: %c. %s\n", first_initial, last_name);
printf("年龄: %d岁\n", age);
printf("身高: %u厘米\n", height_cm);
printf("体重: %.1f千克\n", weight_kg);
printf("月薪: %.2f元\n", salary);
printf("电话: %llu\n", phone);
return 0;
}
输出结果:
plaintext
===== 个人信息 =====
姓名: J. Smith
年龄: 30岁
身高: 175厘米
体重: 72.5千克
月薪: 5896.75元
电话: 13812345678
六、扩展练习
6.1 练习 1:温度转换器
编写程序,将摄氏度转换为华氏度,公式:华氏度 = 摄氏度 × 1.8 + 32
c
运行
#include
int main() {
float celsius, fahrenheit;
printf("请输入摄氏度: ");
scanf("%f", &celsius);
fahrenheit = celsius * 1.8 + 32;
printf("%.1f 摄氏度 = %.1f 华氏度\n", celsius, fahrenheit);
return 0;
}
运行示例:
plaintext
请输入摄氏度: 25
25.0 摄氏度 = 77.0 华氏度
6.2 练习 2:字符加密器
编写程序,对单个字符进行简单加密(将字符的 ASCII 值加 3)
c
运行
#include
int main() {
char original, encrypted;
printf("请输入一个字符: ");
scanf("%c", &original);
encrypted = original + 3; // 加密:ASCII值加3
printf("原始字符: %c (ASCII: %d)\n", original, original);
printf("加密字符: %c (ASCII: %d)\n", encrypted, encrypted);
return 0;
}
运行示例:
plaintext
请输入一个字符: A
原始字符: A (ASCII: 65)
加密字符: D (ASCII: 68)
七、总结与常见问题解答
7.1 核心知识点回顾
- C 语言的基本数据类型包括整型、浮点型和字符型
- 整型分为 int、short、long、long long 及其无符号版本,区别在于表示范围
- 浮点型分为 float、double 和 long double,区别在于精度和范围
- 字符型用于存储单个字符,本质是 8 位整型,存储的是字符的 ASCII 值
- 转义字符用于表示无法直接输入的特殊字符
- 选择数据类型时应遵循 "够用就好" 的原则,同时考虑范围和精度需求
7.2 常见问题解答
Q1:如何确定应该使用 int 还是 long?
A1:通常情况下,优先使用 int,它在大多数系统上是性能最优的类型。当需要存储的整数可能超过 int 的范围(20 亿左右)时,才需要使用 long 或 long long。
Q2:float 和 double 应该如何选择?
A2:double 的精度和范围都优于 float,且在现代计算机上,double 的运算速度并不比 float 慢。因此,除非有特殊原因(如需要大量存储浮点数以节省内存),否则建议优先使用 double。
Q3:为什么字符型可以存储小整数?
A3:在 C 语言中,char 本质上是一种 8 位整型(signed char 范围 - 128 到 127,unsigned char 范围 0 到 255)。存储字符时,实际存储的是该字符的 ASCII 码(整数),因此 char 也可以作为小整数使用。
Q4:为什么比较浮点型变量时不能直接使用 ==?
A4:由于二进制存储方式的限制,许多十进制小数无法精确表示,会存在微小的精度误差。因此,比较浮点型变量时,应该检查它们的差值是否小于一个很小的误差范围(如 1e-6)。

个人主页:编程攻城狮
人生格言:得知坦然 ,失之淡然


共勉:
今天我们学习了 C 语言的基本数据类型,它们是构建程序的 "基本积木"。掌握这些基础知识,让我们能够处理各种类型的数据,为编写更复杂的程序打下了基础。
在下一篇内容中,我们将学习 C 语言中的运算符和表达式。运算符用于对数据进行各种操作(如算术运算、比较运算、逻辑运算等),而表达式则是运算符和操作数的组合。这些知识将帮助我们实现程序中的各种计算和逻辑判断,让程序具备更强的处理能力。

浙公网安备 33010602011771号