语句
在C语言中,表达式和语句是构成程序的基本元素。本节和下一章节我们就围绕它们展开讲一讲其中的C语言基础语法。
首先,让我们区分这两个概念:
- ,语句是代码中的一个完整的,可以执行的步骤。
- 语句的作用复杂多样,常用于构建程序逻辑,如循环语句、条件判断语句、跳转语句等。
,表达式是由变量、常量(称之为操作数)和运算符(也叫操作符)组成的序列,
表达式可以非常简单,如一个单独的常量或变量,或者非常复杂,如包含多个运算符和函数调用的组合。
表达式的作用就是计算值、赋值、函数调用等。
在C语言中,语句和表达式实际上并没有明显的绝对界限,它们的关系是:
- 任何表达式只要直接加上一个分号,立刻就会成为一条语句。比如
a = 10
是一个赋值表达式,但只要加上";",就会变成一个赋值语句。表达式语句是语句最简单的形式。 - 语句不仅限于表达式,比如选择、循环等语句,语句可以更多的影响程序的逻辑。
在表达式中,最重要、最核心的就是连接表达式中常量、变量的运算符了,所以本小节我们主要研究C语言的运算符。
C 语言拥有异常丰富的运算符,比较常见和常用的有以下运算符:
- 算术运算符
- 赋值运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 三目运算符
这些运算符,又可以根据操作数的多少,分为:
- 一元运算符,只需要一个操作数的运算符
- 二元运算符,需要两个操作数的运算符,多数运算符都属于二元运算符。
- 三目运算符,自然就是需要三个操作数的运算符。
下面逐一学习一下。
表达式
C 语言的一个特点就是它更多地强调表达式而不是语句。表达式是用来计算某个值的公式;最简单的表达式就是变量和常量。表达式可以用运算符进行连接,从而创建出更复杂的表达式,比如 a + (b * c)。
C 语言拥有异常丰富的运算符:算术运算符,赋值运算符,关系运算符,判等运算符,逻辑运算符,位运算符...
C 语言有一条不同寻常的规则,那就是任何表达式都可以用作语句。换句话说,不论表达式是什么类型,计算什么结果,我们都可以通过在后面添加分号将其转换成语句。例如,我们可以这样将表达式 ++i 转换成语句:
++i;
执行这条语句时,首先会计算表达式++i 的值,之后这个值会被丢弃,然后执行下一条语句。
表达式是C/C++中产生值的语句。表达式可以包含常量、变量、操作符和函数调用。
操作符是一种操作,它作用于一个或多个值并产生一个新值。C/C++ 中有许多不同的操作符,包括:
- 算术运算符:
+
、-
、*
、/
、%
- 关系运算符:
==
、!=
、<
、>
、<=
、>=
- 逻辑运算符:
&&
、||
、!
- 位运算符:
&
、|
、^
、~
、<<
、>>
函数调用
函数调用是一种调用函数并执行其代码的方式。函数调用包含函数名及其参数(如果需要)。例如:
cout << "Hello, world!" << endl;
表达式类型
表达式可以是不同类型的:
- 整型表达式:产生整数值的表达式。
- 浮点表达式:产生浮点值的表达式。
- 字符表达式:产生字符值的表达式。
- 字符串表达式:产生字符串值的表达式。
- 布尔表达式:产生布尔值的表达式(true 或 false)。
表达式求值
表达式按优先级从左到右求值。优先级由操作符的类型决定。括号可以用来覆盖优先级。
例如,以下表达式的求值为 10:
10 + 5 * 2
因为乘法操作符(*)的优先级高于加法操作符(+)。
示例
以下是一些表达式示例:
x + y
:加法表达式a == b
:关系表达式!c
:逻辑表达式(x & y) << 2
:位运算表达式sqrt(x)
:函数调用表达式
重要提示
- 表达式可以嵌套在其他表达式中。
- 表达式可以作为语句的一部分或作为函数调用的参数。
- 表达式的类型必须与它所在上下文的预期类型兼容。
表达式的主要作用和副作用
为了更好的描述C语言当中运算符组成的表达式作用,我们引入两个重要的概念:
- 表达式的主要作用。表达式的一个特点就是必然会得到一个结果,
- 表达式的副作用。比如说:
- 修改了变量的值(最常见的)
- 执行了某些I/O操作,如打印到控制台或从文件读取数据。
- 调用函数,函数中执行了一些操作
- ....
举几个例子:
比如表达式5 + 2
,其主要作用是计算得出了一个结果值,也就是7,当然它没有副作用。
但假如是表达式int x = 7
,在这个表达式中就是7。赋值表达式显然是有副作用的,副作用就是改变了变量x的值。
函数调用也是一个典型的表达式,比如test()
,假如这次函数调用返回值是100,那么这个表达式的主要作用就是100这个返回值。再假如函数内部进行了I/O操作,将数据打印到了屏幕上,那么I/O操作就是表达式的副作用。
副作用是表达式非常重要的一个效果,它使得表达式可以进行计算值之外的操作,这在很多时候都是非常有用的。
但过于依赖副作用也会导致程序的执行具有更多的不可预测性,使得代码可读性下降,比如:
int arr[] = {1, 2, 3, 4, 5};
int i = 0;
while (i < 5) {
printf("%d ", arr[i++]); // 这行代码的执行需要依赖i++的副作用
}
循环控制变量i的增加,就需要依赖i++
的副作用,这无疑增加了复杂性,降低了可读性。如果改成下面:
printf("%d ", arr[i]);
i++;
代码可读性明显更好。