数据类型是C语言的基础,它决定了数据的存储方式和操作方式。东巴文(db-w.cn) 将带你深入理解C语言的数据类型,掌握数据的本质。
💡 东巴文观点:数据类型就像不同规格的容器,选择合适的容器才能高效存储和处理数据。
东巴文数据类型分类图:
C语言数据类型
├── 基本类型
│ ├── 整数类型
│ │ ├── char(字符型)
│ │ ├── short(短整型)
│ │ ├── int(整型)
│ │ ├── long(长整型)
│ │ └── long long(长长整型)
│ ├── 浮点类型
│ │ ├── float(单精度)
│ │ ├── double(双精度)
│ │ └── long double(长双精度)
│ └── 枚举类型
│ └── enum
├── 构造类型
│ ├── 数组类型
│ ├── 结构体类型
│ │ └── struct
│ ├── 共用体类型
│ │ └── union
│ └── 枚举类型
│ └── enum
├── 指针类型
│ └── type *
└── 空类型
└── void
东巴文整数类型表:
| 类型 | 字节数 | 取值范围 | 东巴文示例 | 东巴文应用场景 |
|---|---|---|---|---|
char |
1 | -128 ~ 127 | char c = 'A'; |
字符、小范围整数 |
unsigned char |
1 | 0 ~ 255 | unsigned char uc = 255; |
字节、颜色值 |
short |
2 | -32768 ~ 32767 | short s = 1000; |
节省内存的小整数 |
unsigned short |
2 | 0 ~ 65535 | unsigned short us = 50000; |
端口号、文件属性 |
int |
4 | -2147483648 ~ 2147483647 | int i = 100000; |
一般整数运算 |
unsigned int |
4 | 0 ~ 4294967295 | unsigned int ui = 4000000000; |
大计数、位运算 |
long |
4/8 | 平台相关 | long l = 100000L; |
大整数 |
unsigned long |
4/8 | 平台相关 | unsigned long ul = 100000UL; |
文件大小、地址 |
long long |
8 | ±9.2×10¹⁸ | long long ll = 1000000000000LL; |
超大整数 |
unsigned long long |
8 | 0 ~ 1.8×10¹⁹ | unsigned long long ull = 1000000000000ULL; |
极大计数 |
#include <stdio.h>
#include <limits.h>
int main() {
printf("=== 东巴文数据类型大小查询 ===\n\n");
printf("整数类型:\n");
printf("char: %zu 字节, 范围: %d ~ %d\n",
sizeof(char), CHAR_MIN, CHAR_MAX);
printf("short: %zu 字节, 范围: %d ~ %d\n",
sizeof(short), SHRT_MIN, SHRT_MAX);
printf("int: %zu 字节, 范围: %d ~ %d\n",
sizeof(int), INT_MIN, INT_MAX);
printf("long: %zu 字节, 范围: %ld ~ %ld\n",
sizeof(long), LONG_MIN, LONG_MAX);
printf("long long: %zu 字节, 范围: %lld ~ %lld\n",
sizeof(long long), LLONG_MIN, LLONG_MAX);
return 0;
}
东巴文提示:字节数可能因平台而异,使用 sizeof 查看实际大小。
东巴文整数字面量表示法:
#include <stdio.h>
int main() {
// 十进制
int dec = 255;
// 八进制(以0开头)
int oct = 0377; // 等于255
// 十六进制(以0x或0X开头)
int hex1 = 0xFF; // 等于255
int hex2 = 0xff; // 等于255
// 二进制(C23标准,以0b或0B开头)
int bin = 0b11111111; // 等于255
// 后缀
long l = 255L;
unsigned int ui = 255U;
unsigned long ul = 255UL;
long long ll = 255LL;
printf("十进制:%d\n", dec);
printf("八进制:%d\n", oct);
printf("十六进制:%d\n", hex1);
return 0;
}
#include <stdio.h>
#include <limits.h>
int main() {
int max = INT_MAX;
printf("最大值:%d\n", max);
printf("最大值 + 1:%d\n", max + 1); // 溢出,变成最小值
unsigned int umax = UINT_MAX;
printf("无符号最大值:%u\n", umax);
printf("无符号最大值 + 1:%u\n", umax + 1); // 溢出,变成0
return 0;
}
东巴文警告:整数溢出是未定义行为,要特别注意!
东巴文浮点类型表:
| 类型 | 字节数 | 有效数字 | 取值范围 | 东巴文示例 | 东巴文应用 |
|---|---|---|---|---|---|
float |
4 | 6-7位 | ±3.4E38 | float f = 3.14f; |
一般浮点运算 |
double |
8 | 15-16位 | ±1.7E308 | double d = 3.14159; |
精确计算 |
long double |
12/16 | 18-19位 | 更大 | long double ld = 3.14159L; |
高精度计算 |
#include <stdio.h>
int main() {
// 小数形式
double d1 = 3.14;
double d2 = .5; // 等于0.5
double d3 = 5.; // 等于5.0
// 指数形式
double d4 = 3.14e2; // 等于314.0
double d5 = 3.14E-2; // 等于0.0314
// 后缀
float f = 3.14f;
double d = 3.14;
long double ld = 3.14L;
printf("d1 = %f\n", d1);
printf("d4 = %f\n", d4);
printf("d5 = %f\n", d5);
return 0;
}
#include <stdio.h>
int main() {
float a = 0.1f;
float b = 0.2f;
float c = a + b;
printf("a = %.20f\n", a);
printf("b = %.20f\n", b);
printf("a + b = %.20f\n", c);
printf("0.3 = %.20f\n", 0.3f);
// 浮点数比较
if (c == 0.3f) {
printf("相等\n");
} else {
printf("不相等\n"); // 可能输出这个
}
return 0;
}
东巴文提示:浮点数有精度问题,不能直接用 == 比较!
#include <stdio.h>
#include <math.h>
int main() {
double a = 0.1 + 0.2;
double b = 0.3;
// ❌ 错误的比较方式
if (a == b) {
printf("相等\n");
}
// ✅ 正确的比较方式
double epsilon = 1e-9; // 精度阈值
if (fabs(a - b) < epsilon) {
printf("相等(误差范围内)\n");
}
return 0;
}
东巴文字符类型说明:
char 本质上是整数类型东巴文ASCII码速查表:
| 字符 | ASCII码 | 字符 | ASCII码 | 字符 | ASCII码 |
|---|---|---|---|---|---|
| '0' | 48 | 'A' | 65 | 'a' | 97 |
| '1' | 49 | 'B' | 66 | 'b' | 98 |
| '2' | 50 | 'C' | 67 | 'c' | 99 |
| ... | ... | ... | ... | ... | ... |
| '9' | 57 | 'Z' | 90 | 'z' | 122 |
东巴文技巧:
#include <stdio.h>
int main() {
char c1 = 'A';
char c2 = 65; // 与'A'相同
printf("字符:%c, ASCII码:%d\n", c1, c1);
printf("字符:%c, ASCII码:%d\n", c2, c2);
// 字符运算
char lower = 'a';
char upper = lower - 32; // 转大写
printf("小写:%c, 大写:%c\n", lower, upper);
// 判断字符类型
char ch = '5';
if (ch >= '0' && ch <= '9') {
printf("%c 是数字\n", ch);
}
if (ch >= 'A' && ch <= 'Z') {
printf("%c 是大写字母\n", ch);
}
if (ch >= 'a' && ch <= 'z') {
printf("%c 是小写字母\n", ch);
}
return 0;
}
东巴文转义字符表:
| 转义字符 | 含义 | ASCII码 | 东巴文说明 |
|---|---|---|---|
\n |
换行 | 10 | 移到下一行开头 |
\r |
回车 | 13 | 移到当前行开头 |
\t |
水平制表 | 9 | 跳到下一个制表位 |
\v |
垂直制表 | 11 | 垂直跳格 |
\b |
退格 | 8 | 删除前一个字符 |
\f |
换页 | 12 | 换页 |
\a |
响铃 | 7 | 系统响铃 |
\\ |
反斜杠 | 92 | 输出反斜杠 |
\' |
单引号 | 39 | 输出单引号 |
\" |
双引号 | 34 | 输出双引号 |
\? |
问号 | 63 | 输出问号 |
\0 |
空字符 | 0 | 字符串结束标志 |
\ooo |
八进制 | - | 八进制表示字符 |
\xhh |
十六进制 | - | 十六进制表示字符 |
// 使用整数表示布尔值
int is_true = 1; // 真
int is_false = 0; // 假
#include <stdio.h>
#include <stdbool.h>
int main() {
bool is_passed = true;
bool is_failed = false;
printf("通过:%d\n", is_passed); // 1
printf("失败:%d\n", is_failed); // 0
if (is_passed) {
printf("恭喜通过!\n");
}
return 0;
}
东巴文说明:C语言中,0表示假,非0表示真。
东巴文void用途表:
| 用途 | 示例 | 东巴文说明 |
|---|---|---|
| 函数无返回值 | void func(void) |
函数不返回任何值 |
| 函数无参数 | int func(void) |
函数不接受任何参数 |
| 通用指针 | void *ptr |
可以指向任何类型 |
| 函数返回通用指针 | void *malloc(size_t size) |
返回通用指针 |
#include <stdio.h>
// 无返回值的函数
void printMessage(void) {
printf("东巴文教程 - db-w.cn\n");
}
// 无参数的函数
int getNumber(void) {
return 42;
}
int main() {
// 调用无返回值函数
printMessage();
// 调用无参数函数
int num = getNumber();
printf("数字:%d\n", num);
// void指针
int x = 10;
void *ptr = &x;
int *intPtr = (int *)ptr;
printf("值:%d\n", *intPtr);
return 0;
}
const int MAX = 100; // 常量,不能修改
const char *str = "东巴文"; // 指向常量的指针
东巴文说明:const 变量必须在定义时初始化,之后不能修改。
volatile int flag; // 易变变量,每次都从内存读取
东巴文应用:用于硬件寄存器、多线程共享变量等。
void func(int * restrict a, int * restrict b) {
// a和b不会指向同一内存区域
}
东巴文说明:restrict 是C99新增的限定符,用于优化。
void function() {
auto int x = 10; // 默认,通常省略auto
}
东巴文说明:局部变量默认是 auto 类型,自动创建和销毁。
#include <stdio.h>
void counter() {
static int count = 0; // 静态局部变量
count++;
printf("调用次数:%d\n", count);
}
int main() {
counter(); // 输出:1
counter(); // 输出:2
counter(); // 输出:3
return 0;
}
东巴文说明:static 变量只初始化一次,生命周期贯穿整个程序。
// file1.c
int global_var = 100;
// file2.c
extern int global_var; // 声明外部变量
void function() {
printf("%d\n", global_var);
}
void function() {
register int i; // 建议存储在寄存器中
for (i = 0; i < 1000000; i++) {
// 频繁使用的变量
}
}
东巴文提示:register 只是建议,编译器可能忽略。
东巴文隐式转换规则:
#include <stdio.h>
int main() {
int i = 10;
float f = i; // int → float
double d = f; // float → double
printf("int: %d\n", i);
printf("float: %f\n", f);
printf("double: %lf\n", d);
return 0;
}
东巴文转换等级:
long double > double > float > unsigned long long > long long >
unsigned long > long > unsigned int > int
#include <stdio.h>
int main() {
int a = 5, b = 2;
// 整数除法
int result1 = a / b;
printf("整数除法:%d\n", result1); // 2
// 浮点除法(强制转换)
float result2 = (float)a / b;
printf("浮点除法:%f\n", result2); // 2.500000
// 另一种方式
float result3 = a / (float)b;
printf("浮点除法:%f\n", result3); // 2.500000
return 0;
}
#include <stdio.h>
int main() {
// 大类型转小类型:可能丢失精度
double d = 3.14159;
int i = (int)d;
printf("double %f → int %d\n", d, i); // 3
// 溢出
long big = 3000000000L;
int small = (int)big;
printf("long %ld → int %d\n", big, small); // 可能溢出
return 0;
}
东巴文警告:类型转换可能导致数据丢失或溢出,要谨慎使用!
sizeof(类型) // 类型大小
sizeof 变量 // 变量大小
sizeof 变量 // 变量大小(可省略括号)
#include <stdio.h>
int main() {
printf("=== 东巴文数据类型大小查询 ===\n\n");
// 基本类型
printf("基本类型:\n");
printf("char: %zu 字节\n", sizeof(char));
printf("short: %zu 字节\n", sizeof(short));
printf("int: %zu 字节\n", sizeof(int));
printf("long: %zu 字节\n", sizeof(long));
printf("long long: %zu 字节\n", sizeof(long long));
printf("float: %zu 字节\n", sizeof(float));
printf("double: %zu 字节\n", sizeof(double));
printf("long double: %zu 字节\n", sizeof(long double));
// 变量
int x = 10;
double y = 3.14;
printf("\n变量:\n");
printf("x: %zu 字节\n", sizeof x);
printf("y: %zu 字节\n", sizeof y);
// 数组
int arr[10];
printf("\n数组:\n");
printf("arr: %zu 字节\n", sizeof(arr));
printf("arr 元素个数:%zu\n", sizeof(arr) / sizeof(arr[0]));
return 0;
}
东巴文提示:sizeof 返回 size_t 类型,使用 %zu 格式输出。
typedef int INTEGER;
typedef float REAL;
typedef char* STRING;
INTEGER x = 10;
REAL y = 3.14f;
STRING name = "东巴文";
typedef struct {
char name[50];
int age;
float score;
} Student;
Student stu1 = {"张三", 20, 85.5};
typedef int (*CompareFunc)(int, int);
int max(int a, int b) {
return a > b ? a : b;
}
CompareFunc func = max;
东巴文建议:使用 typedef 可以简化复杂的类型声明,提高代码可读性。
// ✅ 根据数据范围选择类型
unsigned char age = 25; // 年龄:0-255
unsigned short port = 8080; // 端口号:0-65535
int studentCount = 50000; // 学生数量
long long fileSize = 1000000000; // 文件大小
// ❌ 类型选择不当
int age = 25; // 浪费内存
short port = 8080; // 可能溢出
#include <stdio.h>
#include <limits.h>
int main() {
int a = INT_MAX;
// ❌ 可能溢出
int b = a + 1;
// ✅ 检查溢出
if (a > INT_MAX - 1) {
printf("会溢出!\n");
} else {
int b = a + 1;
}
return 0;
}
#include <stdio.h>
#include <math.h>
int main() {
double a = 0.1 + 0.2;
double b = 0.3;
// ❌ 错误
if (a == b) { }
// ✅ 正确
if (fabs(a - b) < 1e-9) { }
return 0;
}
// ✅ 使用typedef提高可读性
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
BYTE age = 25;
WORD port = 8080;
DWORD address = 0x7fff0000;
完成本章学习后,请确认:
掌握数据类型后,你可以继续学习:
如果遇到问题,欢迎访问 东巴文(db-w.cn) 获取帮助!
东巴文(db-w.cn) - 让编程学习更简单
📦 东巴文数据类型提示:数据类型是编程的基础,选择合适的数据类型是编写高效程序的关键。在 db-w.cn,我们会通过大量实例帮你掌握数据类型的选择和使用!