C语言类型转换 #
一、类型转换概述 #
1.1 为什么需要类型转换 #
在C语言中,不同类型的数据进行运算时,需要转换为相同类型:
c
int a = 10;
float b = 3.14;
float c = a + b;
1.2 类型转换分类 #
text
类型转换
├── 隐式转换(自动转换)
│ ├── 整数提升
│ ├── 算术转换
│ └── 赋值转换
└── 显式转换(强制转换)
└── (type)value
二、隐式转换 #
2.1 赋值转换 #
将值赋给不同类型的变量时自动转换:
c
int a = 10;
float b = a;
double c = b;
转换规则:
- 小类型 → 大类型:安全
- 大类型 → 小类型:可能丢失数据
c
double d = 3.14159;
int a = d;
printf("%d\n", a);
2.2 整数提升 #
小于int的整数类型自动提升为int:
c
char a = 10;
char b = 20;
int c = a + b;
c
#include <stdio.h>
int main() {
char a = 127;
char b = 1;
int c = a + b;
printf("char运算结果: %d\n", c);
return 0;
}
输出:
text
char运算结果: 128
2.3 算术转换 #
不同类型运算时,自动转换为较大类型:
text
long double
↑
double
↑
float
↑
unsigned long long
↑
long long
↑
unsigned long
↑
long
↑
unsigned int
↑
int
示例:
c
#include <stdio.h>
int main() {
int a = 5;
float b = 2.0f;
printf("int / int = %d\n", 5 / 2);
printf("int / float = %f\n", a / b);
printf("float / int = %f\n", b / a);
return 0;
}
输出:
text
int / int = 2
int / float = 2.500000
float / int = 0.400000
2.4 有符号与无符号 #
有符号与无符号运算时,转换为无符号:
c
#include <stdio.h>
int main() {
int a = -5;
unsigned int b = 10;
if (a < b) {
printf("a < b\n");
} else {
printf("a >= b\n");
}
return 0;
}
输出:
text
a >= b
原因:a被转换为无符号数,变成很大的正数。
2.5 隐式转换示例 #
c
#include <stdio.h>
int main() {
char c = 'A';
short s = 100;
int i = 1000;
long l = 100000L;
float f = 3.14f;
double d = 3.14159;
printf("char + int: %d\n", c + i);
printf("short * float: %f\n", s * f);
printf("int / double: %f\n", i / d);
printf("long + double: %f\n", l + d);
return 0;
}
三、显式转换 #
3.1 强制类型转换语法 #
c
(type) expression
3.2 基本用法 #
浮点转整数:
c
double d = 3.14159;
int a = (int)d;
printf("%d\n", a);
整数转浮点:
c
int a = 10;
int b = 4;
double c = (double)a / b;
printf("%f\n", c);
指针类型转换:
c
int a = 0x12345678;
char* p = (char*)&a;
printf("%x\n", *p);
3.3 指针转换 #
c
#include <stdio.h>
int main() {
int a = 65;
int* pi = &a;
char* pc = (char*)pi;
printf("整数: %d\n", *pi);
printf("字符: %c\n", *pc);
return 0;
}
3.4 void指针 #
c
#include <stdio.h>
void print_value(void* ptr, int type) {
if (type == 0) {
printf("int: %d\n", *(int*)ptr);
} else if (type == 1) {
printf("float: %f\n", *(float*)ptr);
} else if (type == 2) {
printf("char: %c\n", *(char*)ptr);
}
}
int main() {
int a = 10;
float b = 3.14f;
char c = 'A';
print_value(&a, 0);
print_value(&b, 1);
print_value(&c, 2);
return 0;
}
四、转换风险 #
4.1 精度丢失 #
c
#include <stdio.h>
int main() {
double d = 3.14159265358979;
float f = (float)d;
int a = (int)d;
printf("double: %.15f\n", d);
printf("float: %.15f\n", f);
printf("int: %d\n", a);
return 0;
}
输出:
text
double: 3.141592653589790
float: 3.141592741012573
int: 3
4.2 数据溢出 #
c
#include <stdio.h>
int main() {
long big = 3000000000L;
int small = (int)big;
printf("long: %ld\n", big);
printf("int: %d\n", small);
return 0;
}
输出:
text
long: 3000000000
int: -1294967296
4.3 符号问题 #
c
#include <stdio.h>
int main() {
int a = -1;
unsigned int b = (unsigned int)a;
printf("int: %d\n", a);
printf("unsigned: %u\n", b);
return 0;
}
输出:
text
int: -1
unsigned: 4294967295
4.4 指针转换风险 #
c
#include <stdio.h>
int main() {
double d = 3.14;
int* p = (int*)&d;
printf("double: %f\n", d);
printf("int*: %d\n", *p);
return 0;
}
可能导致未定义行为。
五、安全转换 #
5.1 检查范围 #
c
#include <stdio.h>
#include <limits.h>
int safe_double_to_int(double d) {
if (d > INT_MAX || d < INT_MIN) {
printf("警告: 数值超出int范围\n");
return 0;
}
return (int)d;
}
int main() {
double d1 = 123.45;
double d2 = 3e10;
printf("d1: %d\n", safe_double_to_int(d1));
printf("d2: %d\n", safe_double_to_int(d2));
return 0;
}
5.2 使用安全函数 #
c
#include <stdio.h>
#include <stdlib.h>
int main() {
const char* str = "12345";
long num = strtol(str, NULL, 10);
printf("转换结果: %ld\n", num);
return 0;
}
5.3 使用固定宽度类型 #
c
#include <stdio.h>
#include <stdint.h>
int main() {
int32_t a = 100;
int64_t b = 10000000000LL;
printf("int32_t: %d\n", a);
printf("int64_t: %lld\n", b);
return 0;
}
六、常见转换场景 #
6.1 字符串转数字 #
c
#include <stdio.h>
#include <stdlib.h>
int main() {
const char* str1 = "12345";
const char* str2 = "3.14";
int i = atoi(str1);
long l = atol(str1);
double d = atof(str2);
printf("int: %d\n", i);
printf("long: %ld\n", l);
printf("double: %f\n", d);
return 0;
}
6.2 数字转字符串 #
c
#include <stdio.h>
int main() {
char buf[100];
int num = 12345;
sprintf(buf, "%d", num);
printf("字符串: %s\n", buf);
return 0;
}
6.3 大小端转换 #
c
#include <stdio.h>
#include <stdint.h>
uint32_t swap_endian(uint32_t value) {
return ((value & 0xFF000000) >> 24) |
((value & 0x00FF0000) >> 8) |
((value & 0x0000FF00) << 8) |
((value & 0x000000FF) << 24);
}
int main() {
uint32_t num = 0x12345678;
printf("原值: 0x%08X\n", num);
printf("转换: 0x%08X\n", swap_endian(num));
return 0;
}
七、类型转换最佳实践 #
7.1 避免不必要的转换 #
c
int a = 10;
int b = 3;
double c = (double)a / b;
7.2 使用显式转换 #
c
int a = 10;
int b = 4;
double c = a / (double)b;
7.3 注意有符号无符号混用 #
c
int a = -1;
unsigned int b = 1;
if ((unsigned int)a < b) {
printf("正确比较\n");
}
7.4 检查转换结果 #
c
#include <stdio.h>
#include <limits.h>
int main() {
long big = 3000000000L;
if (big > INT_MAX || big < INT_MIN) {
printf("数值超出int范围\n");
} else {
int small = (int)big;
printf("转换结果: %d\n", small);
}
return 0;
}
八、总结 #
隐式转换规则 #
| 情况 | 转换方向 |
|---|---|
| 赋值 | 值 → 变量类型 |
| 运算 | 小类型 → 大类型 |
| 有符号/无符号 | 有符号 → 无符号 |
显式转换语法 #
c
(type) expression
转换风险 #
| 风险 | 说明 |
|---|---|
| 精度丢失 | 浮点转整数 |
| 数据溢出 | 大类型转小类型 |
| 符号错误 | 有符号转无符号 |
最佳实践 #
- 优先使用显式转换
- 注意有符号/无符号混用
- 检查转换范围
- 使用固定宽度类型
下一步,让我们学习存储类!
最后更新:2026-03-26