跳到主要内容

C 语言 - 基本语法

前面我们通过 Hello World 程序了解了 C 程序的基本结构,以及如何编译运行它。这一节我们将进一步学习 C 语言的基本语法,让你对 C 代码的编写更深入一点。

语句

语句(statement)是 C 语言代码的重要组成部分,一个语句可以理解为是程序对计算机的一个操作命令。在 C 语言中,语句可以是简单语句复合语句。简单语句以分号结尾,复合语句由用花括号括起来的一个或多个语句组成,也称为代码块或语句块。

简单语句

在 Hello World 的示例中,使用 printf 打印字符串那行代码就是一个语句:

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

程序结束的返回操作也是一个语句:

return 0;

除此之外,变量的声明、运算等等都是常见的简单语句。例如:

int x = 1;

上面就是一个变量声明语句,声明整数变量 x,并且将值设为 1

C 语言支持将多个语句可以写在一行,例如:

int x; x = 1;

而一个语句也可以写成多行,因为 C 语言是依靠分号判断语句在哪一行结束的。

int x;
x
=
1
;

不过上述两种写法不太符合 C 语言的编程规范,但是对代码的编译运行没有一点影响,只是可能不方便阅读代码。

在 C 语言中,单个分号也是有效语句,称为“空语句”,它可能会出现在循环语句。

;

复合语句

C 语言允许多个语句使用一对大括号 {},组成一个块,也称为复合语句(compounded statement)。在语法上,语句块可以视为多个语句组成的一个复合语句。

{
int x;
x = 1;
}

上面示例中,大括号形成了一个语句块。在复合语句中,大括号的结尾是不需要添加分号的。

常见的符合语句有 if...else 判断语句、for 和 while 循环语句,关于这部分我们将在后面的章节详细介绍。

表达式和赋值

所谓的表达式(expression)就是一个计算式,用来获取值。例如下面代码就是一个表达式,用来获取 1 + 2 这个算术计算的结果。

1 + 2

表达式加上分号,就成了表达式语句。在计算机程序中,表达式语句是一类常见的语句,因为程序主要通过表达式完成各种计算。例如 1 + 2;,但这在程序中并没有意义。只有将表达式的结果保存起来、使用起来,才有意义。

int x;
x = 1 + 2;

上面示例中的 a = 1 + 2; 实际上也是一个赋值语句,将表达式 1+2 的结果赋予变量 x。在 C 语言中,赋值语句使用 = 运算符,= 号也称为赋值号,在 = 左边的称为左值,是被赋值的变量,右边的为右值可以为常量、变量或表达式。关于变量和运算符的介绍,后续章节还会详细展开。

表达式与语句的区别主要是两点:

  • 语句可以包含表达式,但是表达式本身不构成语句。
  • 表达式都有返回值,语句不一定有。因为语句用来执行某个命令,有时候并不需要返回值,比如变量声明语句(int x = 1;)就没有返回值。

空白符

常见的空白符包括空格(Space)、制表符(Tab)和换行符。在 C 语言中,空白符的作用主要是用来帮助编译器区分语法单位。如果语法单位不用空格就能区分,空格就不是必须的,只是为了增加代码的可读性。

例如:下面示例中,intx 之间的空格是必须的,而其他的空格则非必须。

int x = 1;
// 等同于
int x=1;

因此,你甚至可以将上面语句写成这样:

int    x =     1;

C 编译器并不介意,因为对它来说,语法单位之间的多个空格,等同于单个空格。但是如果你正在与他人合作编写代码,我建议你不要这么做。

空白符的另一个常见用法是代码缩进。缩进是指在文本或代码中,将每一行开头的空格或制表符向右移动一定距离,以达到对齐的效果。如果你学习过 Python,你就会知道,缩进是非常重要且必要的。但在 C 语言中,缩进只是为了增强代码可读性,便于区分代码块。也就是说,多层级的代码有没有缩进,其实对于 C 编译器来说并没有差别,没有缩进的代码也是完全可以运行的。

不过,为了方便阅读代码,通常建议在上下级代码中使用统一的缩进,例如使用制表符(Tab)或 4 个空格。有时候为了书写紧凑,也会采用缩写两个空格。

// 缩进四个空格
if (x > 0)
printf("is a positive number\n");

// 缩进两个空格
if (x > 0)
printf("is a positive number\n");

恰当使用空白符对于代码的阅读和维护非常重要,当你积累一定的开发经验后一定会深有体会。如果你想看看空白符使用不当的例子,可以试试搜索“C语言混乱代码大赛”。

注释

简单来说,注释是对代码的说明,大部分编程语言都支持注释语法。在 C 语言中,编译器会在预处理的时候把注释删掉,也就是说,注释对实际代码没有影响。

C 语言的注释支持单行注释多行注释。单行注释以双斜杠 // 开头,从双斜杠到行尾都属于注释。注释可以独立一行,也可以放在一行语句的末尾,例如:

// 这是一行注释

int x = 1; // 这也是注释

多行注释则使用 /**/ 符号包裹,也就是说,它们之间的内容都属于注释。

/* 注释 */

/*
这是一行注释
*/

显然,/* ... */ 也可以用作单行注释,如果在内部分行,则表示多行注释。

/* ... */ 的另外一种不太常见的用法是在行内插在注释,例如在函数声明中插入注释:

int open(char* s /* file name */, int mode);

这种用法通常是用来对函数参数进行说明,而跟在它后面的代码依然会有效执行。

最后,总结一下,// 注释只能是单行,从它开始到行尾都属于注释;而 /* ... */ 更加灵活,只有被它包裹的部分才属于注释,通常用于多行注释,但也可以用作单行注释,或者行内注释。