[C语言]第三章-数据类型&变量

106 阅读10分钟

 

编辑

笔者链接:扑克中的黑桃A

系列专栏:C语言专栏


每日一句

不为外物所动之谓静,

不为外物所实之谓虚。

编辑


目录

每日一句

往期回顾:从 Hello World 走向深入

一.C语言数据类型:内存中的百变容器

1. 字符型(char)—— 内存的微型公寓

2. 整型家族——数据的摩天大楼群

3. 浮点型——精确与近度的艺术

4. 字符串伪类型——字符数组的魔法

二.变量与常量:程序世界的变与不变

1. 变量——会变脸的存储单元

2. 常量——程序界的永恒法则

三.变量作用域:代码江湖的势力范围

四.专家级技巧

1. 类型选择策略

2. 防御性编程

3. 调试技巧

五.终极记忆卡:数据类型核心要点

总结


往期回顾:从 Hello World 走向深入

上一章咱们成功从那个简单的程序入手,揭开main函数的神秘面纱,破解头文件的引入玄机。这一章,我们用sizeof撬开内存,看看int、char、float这些数据类型如何在内存中"安家落户"!最后用变量与常量搭建程序世界的动态与永恒法则——准备好深入C语言的原子层了吗?

一.C语言数据类型:内存中的百变容器

1. 字符型(char)—— 内存的微型公寓

存储特性

char ch = 'A'; // 单引号包裹单个字符
printf("%c → ASCII码值:%d", ch, ch); // 输出:A → 65

内存探秘

类型字节表示范围存储内容
char1-128~127ASCII字符
unsigned char10~255原始二进制数据

💡 冷知识char本质是最小整型,可参与算术运算:

char c = 'B' - 1; // 结果:'A'

2. 整型家族——数据的摩天大楼群

类型对比实验

#include <stdio.h>
#include <limits.h> // 包含各类型极限值定义

int main() {
    printf("=== 整型宇宙的边界 ===\n");
    printf("short最大值:%hd\n", SHRT_MAX);
    printf("int最大值:%d\n", INT_MAX);
    printf("long最大值:%ld\n", LONG_MAX);
    printf("long long最大值:%lld\n", LLONG_MAX);
    return 0;
}

整型全景表

类型字节(64位系统)有符号范围无符号范围适用场景
short2-32,768~32,7670~65,535小型计数器
int4-2.1亿~2.1亿0~42.9亿通用整数存储
long8-922亿亿~922亿亿0~1844亿亿时间戳、大ID
long long8-922亿亿~922亿亿同左天文数字计算

⚠️ 溢出陷阱

short s = 32767;
s += 1; // 溢出!结果变为-32768

编辑

3. 浮点型——精确与近度的艺术

精度对比实验

#include <stdio.h>

int main() {
    float f_val = 1.0f / 3.0f;
    double d_val = 1.0 / 3.0;
    
    printf("float精度:%.20f\n", f_val);
    printf("double精度:%.20f\n", d_val);
    return 0;
}

输出结果

float精度:0.33333334326744080000  // 7位有效数字后失真  
double精度:0.33333333333333331000 // 15位有效数字仍精确

浮点型规格

类型字节有效数字指数范围使用建议
float46~7位±3.4e38图形处理、嵌入式
double815~17位±1.7e308科学计算、金融

🔥 黄金法则

  • 默认浮点常量是double类型,要定义float需加f后缀
  • 避免直接比较浮点数相等:(fabs(a-b) < 1e-6)

4. 字符串伪类型——字符数组的魔法

内存布局揭秘

char str[] = "Hello"; 
// 实际内存:['H','e','l','l','o','\0']
printf("字符串长度:%zu\n", sizeof(str)); // 输出6(含\0

两种存储方式对比

方式示例可修改性内存位置
字符数组char s[]="abc";可修改栈区
字符指针char *p="abc";不可修改常量区

💀 死亡陷阱

char *p = "Hello";
p[0] = 'h'; // 运行时错误!尝试修改常量区

二.变量与常量:程序世界的变与不变

1. 变量——会变脸的存储单元

定义规范

int count;          // 声明
count = 10;         // 赋值
int score = 95;     // 声明并初始化

命名军规

int user_age;      // ✔️ 蛇形命名法(推荐)
int userName;      // ✔️ 驼峰命名法  
int 2bad;          // ❌ 数字开头  
int $price;        // ❌ 非法符号  
int while;         // ❌ 关键字冲突

2. 常量——程序界的永恒法则

三种定义方式

// 方式1:字面常量
printf("%d", 100); 

// 方式2:宏常量(预处理替换)
#define PI 3.1415926
#define SQUARE(x) ((x)*(x)) // 带参宏

// 方式3:const常量(类型安全)
const int MAX = 100;
// MAX = 200; // 编译错误!

宏与const终极对决

特性#defineconst常量
类型检查❌ 无✔️ 有
作用域文件全局遵循作用域规则
调试可见性预处理阶段已替换保留符号信息
内存占用不占内存占用存储空间

编辑

三.变量作用域:代码江湖的势力范围

作用域可视化实验

#include <stdio.h>
int global = 100; // 🌍 全局变量

void test() {
    int local = 50; // 🏡 局部变量
    printf("全局变量:%d, 局部变量:%d\n", global, local);
}

int main() {
    int local = 10; // 🏠 同名局部变量
    printf("main局部变量:%d\n", local); // 输出10(局部优先)
    test();
    // printf("%d", local_in_test); // 错误!跨函数不可见
    return 0;
}

作用域规则总结

编辑

四.专家级技巧

1. 类型选择策略

内存敏感场景:short/char

通用计算:int

高精度需求:double

2. 防御性编程

#define MAX_TEMP 150
if(temperature > MAX_TEMP) {
    shutdown_system();
}

3. 调试技巧

printf("变量地址:%p", &var); // 观察内存布局

五.终极记忆卡:数据类型核心要点

类型字节格式符典型用法注意事项
char1%cchar c='A';本质是1字节整型
int4%dint count=10;默认整数类型
long long8%lldlong long big=1e18;常量需加LL后缀
float4%ffloat pi=3.14f;必须加f后缀
double8%lfdouble precise=1.234;默认浮点类型
字符串N+1%schar s[]="hello";末尾自动补\0

总结

C语言的数据类型系统如同精密的容器仓库,提供了从1字节的char到8字节的double等多种"存储容器",每种类型都有明确的内存占用和数值范围。通过sizeof操作符可以直观探查类型尺寸,而变量与常量的合理运用则构成了程序数据流动性的基础,其中#define宏与const常量的选择体现了C语言灵活与严谨的双重特性。

数据类型的选择直接影响程序性能和正确性,比如short的节省内存与int的通用平衡,float的速度优势与double的精度保障。字符与字符串的独特处理方式展现了C语言贴近硬件的本质,而作用域规则则为变量划定了精确的生命周期边界,全局变量的便利与局部变量的安全形成巧妙互补。

掌握这些基础概念是成为C语言高手的关键第一步,后续的运算符、流程控制等高级特性都建立在此根基之上。理解数据在内存中的真实形态,才能写出既高效又健壮的代码,这正是C语言历经数十年仍屹立不倒的核心竞争力。