C 数据类型

C 数据类型

🎯 学习目标:
掌握 C 语言的基本数据类型、常量与变量定义方式,理解其在内存中的表示和使用场景,为后续开发打下坚实基础。

🔑 核心重点:
C 语言提供了丰富而底层的数据类型系统,包括整型、浮点型、字符型、枚举型等,开发者需根据实际需求选择合适的数据类型。


一、详细讲解

1. 基本数据类型(C23 标准)

类型类别 类型名称 含义说明
整型 char 字符,通常为 1 字节
short 短整型,通常为 2 字节
int 整型,通常为 4 字节
long 长整型
long long 更长整型(C99 引入)
浮点型 float 单精度浮点数
double 双精度浮点数
布尔型 _Bool / bool 布尔值(true/false),需包含 <stdbool.h>
枚举型 enum 枚举常量集合
指针型 type* 指向特定类型的地址

示例代码:

#include <stdio.h>
#include <stdbool.h>

int main(void) {
    char ch = 'A';
    int age = 25;
    float price = 9.99f;
    double pi = 3.141592653589793238;
    bool is_valid = true;

    printf("Size of char: %zu\n", sizeof(ch));
    printf("Size of int: %zu\n", sizeof(age));
    printf("Size of float: %zu\n", sizeof(price));
    printf("Size of double: %zu\n", sizeof(pi));
    printf("Size of bool: %zu\n", sizeof(is_valid));

    return 0;
}

⚠️ 注意:

  • 使用 %zu 来打印 sizeof() 的结果(因为它是 size_t 类型)。
  • 在 CLion 中可以启用 -Wall -Wextra 编译器选项来捕获潜在的类型不匹配问题。

2. 类型修饰符(Type Modifiers)

  • signed / unsigned:控制整型是否带符号
  • short / long:控制整型长度

常见组合示例:

unsigned int u_int = 100;
long l_num = 1000000L;
unsigned long ul_num = 1000000000UL;
long long ll_num = 9223372036854775807LL;

📌 提示:使用后缀 L, UL, LL 等明确指定常量类型,有助于避免溢出或隐式转换错误。


3. void 类型

  • 表示“无类型”,用于函数返回值或指针类型。
  • 不能声明 void 类型的变量。
void do_something(void) {
    // 不返回任何值
}

int main(void) {
    void *ptr;  // 可以指向任意类型
    int a = 10;
    ptr = &a;
    printf("%d\n", *(int*)ptr);  // 必须显式转换回具体类型
    return 0;
}

4. 枚举类型(enum

  • 枚举是一组命名的整数常量集合。
  • 默认从 0 开始递增,也可以自定义值。
enum Color { RED, GREEN, BLUE };  // 默认 0, 1, 2

enum Status {
    SUCCESS = 0,
    ERROR_FILE_NOT_FOUND = -1,
    ERROR_PERMISSION_DENIED = -2
};

5. 类型别名(typedef

  • 使用 typedef 给类型起一个新名字,提高可读性和抽象能力。
typedef unsigned int uint;
typedef struct {
    int x;
    int y;
} Point;

int main(void) {
    uint counter = 0;
    Point p = {10, 20};
    printf("Point (%d, %d)\n", p.x, p.y);
    return 0;
}

⚠️ 注意事项

  • 不同平台和编译器可能对 intlong 等基本类型的大小有不同实现(如 Windows vs Linux)。建议使用 <stdint.h> 中的固定大小类型(如 int32_t, uint64_t)确保跨平台一致性。
  • 避免将 float 用于高精度计算,应优先使用 double
  • void* 是通用指针,但在访问时必须强制转换为具体类型。
  • 枚举值默认是 int 类型,不能直接赋值给其他类型变量而不做强制转换。

🧪 实际案例分析

案例:使用结构体和枚举模拟状态机

#include <stdio.h>

typedef enum {
    IDLE,
    RUNNING,
    PAUSED,
    STOPPED
} State;

typedef struct {
    char name[32];
    State current_state;
} Machine;

void update_machine(Machine *m) {
    switch (m->current_state) {
        case IDLE:
            printf("%s is idle.\n", m->name);
            break;
        case RUNNING:
            printf("%s is running.\n", m->name);
            break;
        case PAUSED:
            printf("%s is paused.\n", m->name);
            break;
        case STOPPED:
            printf("%s is stopped.\n", m->name);
            break;
    }
}

int main(void) {
    Machine robot = {"Robot-Arm", RUNNING};
    update_machine(&robot);

    robot.current_state = PAUSED;
    update_machine(&robot);

    return 0;
}

🔍 说明:

  • 结合了 enumstruct 模拟面向对象中的“对象”行为。
  • 展示了如何通过枚举管理程序状态逻辑。

🧩 拓展练习

  1. 编写一个程序,输入学生的性别(男/女)、年龄、身高(米)和体重(千克),并输出 BMI 值。
  2. 定义一个表示颜色的枚举类型,包含红、绿、蓝三种颜色,并编写函数根据枚举值输出对应英文名称。
  3. 创建一个结构体 Book,包含书名、作者、ISBN、价格,然后创建数组保存多本书信息并遍历输出。
  4. 使用 typedefunsigned long long 定义为 u64,并在程序中测试它的用法。
  5. 使用 <stdint.h> 中的固定大小类型重写你之前的程序,验证其跨平台兼容性。

📚 推荐阅读

  • 《C Primer Plus》第6版 —— 数据类型章节
  • 《The C Programming Language》K&R —— 第二章 数据类型与运算
  • 《C标准库详解》—— <stdint.h><stdbool.h> 等标准头文件介绍
  • 《Understanding and Using C Pointers》—— 深入理解指针与数据类型关系

🧭 下一步建议

你已经掌握了 C 语言的基本数据类型及其使用方法。下一步建议深入学习:

👉 《C 运算符与表达式》—— 掌握各类运算符的优先级、结合性及常见陷阱
同时继续在 CLion 中使用断点调试查看变量在内存中的存储方式,加深对数据类型本质的理解。

是否需要我继续生成下一章内容?

posted @ 2025-06-02 10:40  红尘过客2022  阅读(45)  评论(0)    收藏  举报