C: 基本语法

学C语言的基本语法就像学汉字的笔画——横竖撇捺看似简单,但所有华丽的文章都由它们组合而成。

1. 程序的基本结构

每一个C程序都有一个固定的骨架,不管程序多复杂,核心结构不变:

C
#include <stdio.h>

int main(void) {
    return 0;
}

这是最小的合法C程序——虽然它什么都不做,但结构完整。让我们拆解每一部分:

(1) 预处理指令

#include <stdio.h> 是预处理指令,以 # 开头,在编译之前由预处理器处理。

你还会遇到其他常用头文件:

头文件 提供的功能
<stdio.h> 输入输出(printf、scanf)
<stdlib.h> 通用工具(malloc、exit)
<math.h> 数学函数(sqrt、sin)
<string.h> 字符串操作(strlen、strcpy)
<ctype.h> 字符判断(isdigit、toupper)

(2) main函数

C
int main(void) {
    return 0;
}

🔥 重要main 是C程序唯一的入口点。一个程序只能有一个 main 函数,操作系统调用它来启动你的程序。

(3) 其他写法

你可能在某些教材中看到不同的main写法:

C
int main(int argc, char *argv[])

这种写法可以接收命令行参数,后续章节会详细讲解。现在用 int main(void) 就够了。

⚠️ 避免:有些老教材用 void main(),这不是标准C写法,某些编译器会发出警告。始终使用 int main(void)


2. 语句与分号

C语言中,分号 ; 是语句的结束标志。这和中文的句号类似——一句话说完要加句号,一条语句写完要加分号。

C
int age = 18;
age = age + 1;
printf("I am %d years old\n", age);

每一行都是一条语句,以分号结尾。

常见错误——忘记分号:

C
int age = 18

编译器不认"换行",只认分号。所以理论上你可以把所有代码写在一行:

C
int age = 18; age = age + 1; printf("%d\n", age);

虽然语法合法,但绝不推荐这样写。良好的代码风格是一条语句占一行。

💡 空语句:单独一个分号也是合法语句,称为空语句,什么都不做:

C
;

它在某些特殊场景下有用(如空循环体),但现在不需要关心。


3. 代码块

花括号 {} 包裹的一组语句构成一个代码块(也叫复合语句):

C
int main(void) {
    int x = 10;
    int y = 20;
    int sum = x + y;
    printf("Sum = %d\n", sum);
    return 0;
}

整个 main 函数体就是一个代码块。代码块定义了作用域——在块内声明的变量,块外无法访问。

代码块可以嵌套:

C
int main(void) {
    int a = 1;
    {
        int b = 2;
        printf("a + b = %d\n", a + b);
    }
    return 0;
}

内层代码块可以访问外层的 a,但外层无法访问内层的 b

⚠️ 风格建议:即使代码块只有一条语句,也建议写花括号。这能避免后续添加语句时忘记加花括号的bug。


4. printf函数

printf 是C语言最常用的输出函数,名字来自 print formatted(格式化打印)。

(1) 基本用法

C
printf("Hello, World!\n");

双引号内的内容称为格式字符串,会原样输出(转义字符除外)。

(2) 格式占位符

printf 的强大之处在于格式化输出变量的值:

C
int age = 18;
float height = 1.75f;
char grade = 'A';
printf("Age: %d\n", age);
printf("Height: %.2f\n", height);
printf("Grade: %c\n", grade);

常用占位符:

占位符 对应类型 示例输出
%d int 42
%f float / double 3.140000
%.2f float(保留2位小数) 3.14
%c char A
%s 字符串 hello
%ld long 100000
%x 十六进制整数 2a
%o 八进制整数 52
%% 输出百分号本身 %

💡 多个占位符:可以在一个 printf 中使用多个占位符,按顺序对应后面的参数:

C
int a = 3, b = 4;
printf("%d + %d = %d\n", a, b, a + b);

(3) 宽度与对齐

C
printf("[%5d]\n", 42);
printf("[%-5d]\n", 42);
printf("[%05d]\n", 42);
TEXT 📖 仅展示
[   42]
[42   ]
[00042]

5. 转义字符

在字符串中,有些字符无法直接输入(如换行、制表符),需要用转义字符表示。转义字符以反斜杠 \ 开头:

转义字符 含义 示例
\n 换行 printf("A\nB") 输出A和B各占一行
\t 水平制表符 对齐输出时常用
\\ 反斜杠本身 输出 \ 需要写 \\
\" 双引号 在字符串中输出 "
\' 单引号 在字符中输出 '
\0 空字符 字符串结束标志
\r 回车 光标回到行首
\b 退格 光标左移一格

⚠️ 易错点:输出路径时必须用双反斜杠:

C
printf("C:\\Users\\admin\\file.txt\n");
TEXT 📖 仅展示
C:\Users\admin\file.txt

6. 注释

注释是写给人看的说明文字,编译器会完全忽略。好的注释能让代码更容易理解。

(1) 单行注释

C99引入了 // 风格的单行注释,从 // 到行末的内容都是注释:

C
int score = 100;

(2) 多行注释

/* */ 风格的注释可以跨越多行:

C
/*
 * This program calculates
 * the sum of two numbers
 */
#include <stdio.h>

int main(void) {
    int a = 10;
    int b = 20;
    printf("%d\n", a + b);
    return 0;
}

(3) 注释的最佳实践

注释应该解释为什么(Why),而不是是什么(What)。代码本身已经说明了What,注释要补充的是代码无法表达的设计意图和决策原因。

好的注释:

C
int max_retries = 3;

不必要的注释(代码已经说明了一切):

C
int x = 10;

⚠️ 注意:多行注释不能嵌套。以下写法会导致编译错误:

C
/*
  /* nested comment */
*/

内层的 */ 会提前结束外层注释,导致后面的 */ 成为语法错误。


7. 标识符与关键字

(1) 标识符命名规则

标识符就是你自己起的名字(变量名、函数名等),必须遵循:

合法命名:agestudent_name_countMAX_SIZE

非法命名:2name(数字开头)、my-age(含减号)、int(关键字)

(2) 命名风格

风格 格式 适用场景 示例
snake_case 小写+下划线 变量名、函数名 student_count
UPPER_CASE 全大写+下划线 常量名 MAX_BUFFER_SIZE
CamelCase 首字母大写 自定义类型名 StudentInfo

C语言传统上使用 snake_case 风格,这与Java/C#的camelCase风格不同。保持项目内风格统一最重要。

(3) C99关键字

C99共有37个关键字,全部为小写:

类别 关键字
数据类型 char short int long float double void signed unsigned _Bool _Complex _Imaginary
控制语句 if else switch case default for while do break continue goto return
存储类 auto extern static register typedef inline
结构 struct union enum
其他 const volatile sizeof restrict

这些关键字不需要背,写多了自然就记住了。重要的是知道关键字不能作为标识符使用

▶ 示例

综合运用本节所学知识,写一个展示基本语法的程序:

C
#include <stdio.h>

int main(void) {
    printf("=== Student Info ===\n");
    printf("Name:\t%s\n", "Zhang San");
    printf("Age:\t%d\n", 20);
    printf("Score:\t%.1f\n", 95.5);
    printf("Grade:\t%c\n", 'A');
    printf("====================\n");
    return 0;
}
▶ 试一试
TEXT 📖 仅展示
=== Student Info ===
Name:	Zhang San
Age:	20
Score:	95.5
Grade:	A
====================

这个程序展示了:#include 预处理指令、main 函数结构、printf 格式化输出、\n 换行、\t 制表符对齐,以及 %d%.1f%c%s 四种常用占位符。

❓ 常见问题

Q 为什么C语言用分号而不是换行来分隔语句?
A 因为C语言允许一条语句跨多行书写,也允许一行写多条语句。用分号作为分隔符更灵活,编译器不需要关心代码的排版方式。
Q printf的f是什么意思?
A f代表formatted(格式化)。printf不仅能输出固定文字,还能用%d、%f等占位符把变量的值"填"进输出中,这就是格式化输出的含义。
Q 注释写多了会影响程序运行速度吗?
A 完全不会。编译器在预处理阶段就会删除所有注释,编译后的可执行文件中没有任何注释内容。所以放心写注释,不影响性能。
Q void main和int main到底用哪个?
A 始终用int main(void)。C标准明确规定main函数返回int。void main是某些老编译器的非标准扩展,现代编译器可能发出警告甚至拒绝编译。

📖 小节

📝 作业

  1. 编写程序,用printf输出一个你自己的信息卡片(姓名、年龄、爱好),使用\t对齐
  2. 编写程序,用一次printf调用输出以下内容(使用转义字符实现换行和制表):姓名 张三、年龄 25、城市 北京
  3. 故意在代码中写一个多行注释嵌套的例子,观察编译器的报错信息
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏