2.1变量与基本数据类型

155 阅读3分钟

变量与基本数据类型 ——程序世界的数字积木


一、数据类型:内存空间的身份证

C语言通过数据类型明确变量占用的内存大小和存储格式。以下是常见类型的核心特性:

1. 整型家族

类型内存占用取值范围格式化符号
char1字节-128 ~ 127 或 0 ~ 255%c
short2字节-32768 ~ 32767%hd
int4字节-2147483648 ~ 2147483647%d
long4/8字节取决于系统架构%ld
long long8字节-9e18 ~ 9e18%lld

验证代码

#include <stdio.h>  
#include <limits.h>  int main() {  
    printf("char范围: %d ~ %d\n", CHAR_MIN, CHAR_MAX);  
    printf("int大小: %zu字节\n", sizeof(int));  // sizeof返回size_t类型  
    return 0;  
}  

2. 浮点型家族

类型内存占用精度格式化符号
float4字节6-7位有效数字%f
double8字节15-16位有效数字%lf

精度陷阱示例

float f = 0.1;  
if (f == 0.1) {  // 条件永远不成立!  
    printf("Equal!\n");  
}  
// 因为0.1默认是double类型,float无法精确存储  

3. 特殊类型

  • void:表示无类型,用于函数返回值或指针
  • _Bool:C99新增布尔类型(需包含<stdbool.h>)

二、变量命名与管理

1. 命名规则(铁律)

  • 字母/数字/下划线组成,且不能以数字开头
  • 区分大小写:ageAge是不同的变量
  • 禁止使用关键字(如int、return等)

合法命名示例

int student_count;  
float _sensor_data;  
char serialNumber[20];  

非法命名示例

int 3d_print;    // 数字开头  
char switch;     // 使用关键字  
float user-name; // 含连字符  

2. 作用域与生命周期

变量类型作用域生命周期存储位置
局部变量定义它的代码块内块执行期间
全局变量整个程序程序运行期间数据段
static局部变量定义它的代码块内程序运行期间数据段

示例场景

#include <stdio.h>  int global = 100;  // 全局变量  
​
void func() {  
    static int count = 0;  // 静态局部变量  
    int local = 10;        // 普通局部变量  
    count++;  
    printf("local:%d count:%d\n", local, count);  
}  
​
int main() {  
    func();  // 输出: local:10 count:1  
    func();  // 输出: local:10 count:2  
    // printf("%d", local);  错误!local不可见  
    return 0;  
}  

三、常量定义:const vs #define

1. 语法对比

特性const#define
类型检查✔️ 有明确类型❌ 纯文本替换
作用域遵循变量作用域规则从定义处到文件结束
内存分配占用内存空间不分配内存
调试可见性调试器可查看预处理后消失

2. 使用示例

// const常量  
const float PI = 3.14159;  
const int MAX_USERS = 1000;  
​
// #define宏  
#define TAX_RATE 0.15  
#define CIRCLE_AREA(r) (PI * (r) * (r))  // 带参数的宏  // 危险宏示例  
#define SQUARE(x) x * x  
int val = SQUARE(2+3);  // 展开为2+3*2+3=11,而非25!  
// 应改为:#define SQUARE(x) ((x)*(x))  

四、新手避坑指南

  1. 未初始化变量

    int score;  
    printf("%d", score);  // 输出随机值!  
    
  2. 作用域混淆

    int x = 5;  
    {  
        int x = 10;  // 内层x遮蔽外层x  
        printf("%d", x);  // 输出10  
    }  
    
  3. 宏的副作用

    #define MAX(a,b) a > b ? a : b  
    int m = MAX(3, 5 + 2);  // 展开为3 > 5 + 2 ? 3 : 5 + 27  
    
  4. 误用浮点比较

    float a = 0.1 + 0.2;  
    if (a == 0.3) {  // 永远不成立!  
        // 应使用fabs(a - 0.3) < 1e-6  
    }  
    

五、总结:变量使用决策模板

选择数据类型时

  • 需要整数计算 → 根据范围选int/long
  • 需要小数存储 → 优先选double(精度更高)
  • 存储字符 → 用char,布尔值 → 用_Bool

定义常量时

  • 推荐const(类型安全)
  • 需要条件编译或字符串拼接 → 用#define

🚫 避免以下操作

  • 在循环内定义static变量(导致不可预测的值)
  • 使用全局变量传递数据(破坏封装性)
  • #define定义复杂函数式宏(易引发错误)

终极建议:当你写下int a;时,记住这不是简单的声明——你正在向计算机申请一块内存的使用权。善待每一个变量,就像园丁照料他的植物! 🌱