第1章:基本语法与数据类型
各位同学好,我是你们这门课的老朋友。今天咱们聊聊C语言最基础的东西——变量、常量、数据类型,还有那两个你天天打交道的函数:printf和scanf。
说实话,我见过太多初学者一上来就啃指针、啃链表,结果连个int占几个字节都说不清楚。这就像盖楼不打地基,早晚要塌。所以,咱们老老实实把基础夯实了,后面才能跑得快。
1.1 变量与常量
先问个问题:程序在干什么?说白了,程序就是在处理数据。数据放哪儿?放内存里。怎么找到它?靠变量名。
变量,就是一块内存区域的名字。你可以往里面存值,也可以把值读出来。变量是可以变的——不然怎么叫变量呢?
变量定义的基本形式:
类型 变量名;
类型 变量名 = 初始值;
举个例子:
int age; // 定义了一个整型变量,名字叫age
age = 25; // 给age赋值
int count = 10; // 定义并初始化
常量就好理解了——值不能变。C语言里用const关键字来声明常量:
const int MAX_SIZE = 1024;
const float PI = 3.14159;
注意:常量一旦定义,就不能再修改。如果你试图写 PI = 3.14;,编译器会报错。我曾经在项目里见过有人把常量当变量用,结果程序跑飞了,查了半天才发现是这里的问题。
还有一种常量叫字面常量,就是直接写在代码里的值:
int a = 100; // 100 是整型字面常量
float b = 3.14; // 3.14 是浮点型字面常量
char c = 'A'; // 'A' 是字符型字面常量
1.2 基本数据类型
C语言提供了几种基本数据类型,我列个表给你看:
| 类型 | 关键字 | 占字节数(32位系统) | 取值范围 |
|---|---|---|---|
| 整型 | int | 4 | -2^31 ~ 2^31-1 |
| 短整型 | short | 2 | -32768 ~ 32767 |
| 长整型 | long | 4 或 8 | 取决于系统 |
| 单精度浮点 | float | 4 | 约 ±3.4e38 |
| 双精度浮点 | double | 8 | 约 ±1.8e308 |
| 字符型 | char | 1 | -128 ~ 127 或 0 ~ 255 |
我的经验:在嵌入式开发中,我习惯用 int 作为默认整型,除非明确知道数值范围很小才用 short。为什么?因为很多MCU对 int 的处理效率最高,用 short 反而可能产生额外的类型转换开销。
这里有个容易踩的坑——char到底是有符号还是无符号?标准C没有明确规定,取决于编译器实现。我在一个项目里就吃过这个亏:把char当有符号用,结果在某个ARM编译器上它默认是无符号的,导致比较逻辑全错了。所以,如果你需要明确符号,请写成 signed char 或 unsigned char。
1.3 printf与scanf的使用
这两个函数是C语言的"嘴"和"耳朵"。printf负责输出,scanf负责输入。它们都在 stdio.h 头文件里。
printf——格式化输出
基本用法:
printf("格式控制字符串", 输出项列表);
格式控制字符串里用格式说明符来占位:
| 格式说明符 | 对应数据类型 | 示例 |
|---|---|---|
| %d | int | printf("%d", 100); |
| %f | float / double | printf("%f", 3.14); |
| %c | char | printf("%c", 'A'); |
| %s | 字符串 | printf("%s", "hello"); |
| %x | 十六进制 | printf("%x", 255); |
来个完整的例子:
#include <stdio.h>
int main() {
int age = 30;
float height = 1.75;
char grade = 'A';
printf("年龄:%d\n", age);
printf("身高:%.2f米\n", height); // .2f 表示保留两位小数
printf("等级:%c\n", grade);
return 0;
}
输出结果:
年龄:30
身高:1.75米
等级:A
scanf——格式化输入
scanf的用法和printf类似,但有个关键区别:变量前面要加 & 符号(取地址符)。
scanf("格式控制字符串", &变量1, &变量2, ...);
看个例子:
#include <stdio.h>
int main() {
int num;
float price;
char ch;
printf("请输入一个整数:");
scanf("%d", &num);
printf("请输入一个浮点数:");
scanf("%f", &price);
printf("请输入一个字符:");
scanf(" %c", &ch); // 注意 %c 前面有个空格,用来跳过空白字符
printf("你输入了:%d, %.2f, %c\n", num, price, ch);
return 0;
}
我曾经踩过的坑:用scanf读字符时,如果前面刚读过数字,输入缓冲区里会残留一个换行符。这时候 scanf("%c", &ch); 会直接读到那个换行符,而不是你想要的字符。解决办法就是在%c前面加个空格:scanf(" %c", &ch);。这个小问题当年让我调试了整整一个下午。
1.4 格式化输出的进阶技巧
printf的格式化能力远不止上面那些。我常用的几个技巧:
- 指定宽度:
printf("%5d", 123);输出" 123"(右对齐,占5位) - 左对齐:
printf("%-5d", 123);输出"123 " - 补零:
printf("%05d", 123);输出"00123" - 精度控制:
printf("%.3f", 3.14159);输出"3.142"
这些在嵌入式调试时特别有用。比如打印寄存器值,我习惯用 %08x 来确保总是显示8位十六进制数,一眼就能看出高低字节。
知识体系总览
下面这张图把本章的核心内容串起来了,你可以对照着复习:
嗯,这一章的内容就这些。别看都是基础,但基础不牢,地动山摇。我建议你把每个代码示例都亲手敲一遍,别光看。看十遍不如写一遍,这是我从入行到现在一直坚持的习惯。
记住:变量要初始化,scanf别忘了加&,printf的格式说明符要和数据类型匹配。这三条记住了,能帮你省下不少调试时间。
公众号:蓝海资料掘金营,微信deep3321