第 2 集 · B1 · 7 分钟
C 语言 · 第2集 · if 分支怎么选
从 Hello World、循环、递归讲到汉诺塔和动态规划,句子短,适合跟读。 开头:在C语言中如下所示。

中俄字幕
в Си следующим образом.
在C语言中如下所示。
Давайте я расставлю те значки, которые являются обязательными.
我来标出那些必需的符号。
Ну понятно, что без if'а никуда, но вот эти скобки и вот эта точка с запятой
显然,if语句必不可少,但这些括号和这个分号
являются обязательными.
是必需的。
Обязательными.
必需的。
Она заканчивает оператор номер один, является его точкой завершения, все, он
它结束了第一个语句,是该语句的终止符,到此为止,该语句
закончился. Да, несмотря на то, что дальше идет else, в языке Pascal именно в этом
就结束了。是的,尽管后面还有else,但在Pascal语言中,此处恰恰不需要分号;而在C语言中,分号是必须的。
месте как раз не требовалась точка с запятой, в языке Си она нужна обязательно.
在C语言中,分号是必须的。
Дальше блок else- это оператор номер два, который будет выполнен, если условие
接下来的else块是第二个语句,当条件为假时将执行该语句。
окажется ложным.
结果为假。
Очень важно понимать, что вот это условие в языке Си, не всегда это важно понимать,
理解C语言中的这个条件非常重要,虽然并非总是需要理解这一点,
но лучше, если вы будете знать, что это условие является арифметическим, а не
但最好还是清楚:该条件属于算术类型,而非
логическим. То есть это условие либо равно нулю, тогда оно ложно, либо не равно
逻辑类型。也就是说,若该条件等于零,则为假;若不等于
нулю, например, 2, 5 или 100- это все такая же правда, как.
零(例如2、5或100),则同样视为真。
и единица. Понятно, да?
明白吗?
То есть если тут тысяча миллионов или минус один, то это правда.
也就是说,如果此处是十亿或负一,结果仍为真。
Вот. Ну чаще всего там, конечно, оказывается либо 0, либо 1, ну либо логический тип,
通常情况下,结果往往仅为0或1,或者——
если вы пользуетесь современным стандартом.
如果您使用现代标准,则可能是布尔类型。
Соответственно, после else вот эта точка с запятой, она тоже обязательно есть.
相应地,在else之后的这个分号也必须存在。
Надо понимать, что поток исполнения, он пройдет либо по прямой ветке, то есть
需要明确的是,执行流将仅沿其中一条分支运行,即要么走主分支,
выполнится этот, либо по альтернативной.
将执行此操作,或执行替代操作。
Никогда, у нас не квантовая механика, не может быть такого, что оба оператора
绝不可能——我们处理的不是量子力学,不可能两个操作符同时执行。
выполнятся сразу.
会同时执行。
Ни при каком состоянии вот этого условия.
在该条件的任何状态下都不可能。
Конечно, если ваш поток исполнения зациклен, у вас есть цикл, да, то может быть, что
当然,如果您的执行流处于循环中(即存在一个循环),那么有可能:
на одной итерации вы прошли вот тут, а на второй итерации вот тут, на третьей. . .
在第一次迭代时执行了此处,第二次迭代时执行了此处,第三次……
В общем, там условие проверяется много раз, и оно, естественно, может оказаться
总之,该条件会被多次检查,因此其结果自然可能不同。
разным. давайте посмотрим на неполную форму оператора if.
我们来看一下if语句的不完整形式。
В этом случае мы просто берем и выкидываем вот эту вот вторую часть.
此时,我们直接省略第二部分。
да, что это будет означать?
那么,这表示什么意思呢?
Что у нас если нет, то ничего делать не надо.
如果没有,那就什么都不用做。
Ничего делать не надо.
什么都不用做。
Все, мы просто пропускаем
好了,我们直接跳过。
второе действие.
第二个操作。
И еще важно понимать, что поток исполнения продолжается.
另外,重要的是要明白执行流程会继续下去。
То есть у вас есть некоторое действие, которое будет выполнено по- любому.
也就是说,总会执行某个操作。
Оно в любом случае, неважно, было условие истинным или нет.
无论条件是否为真,该操作都会执行。
Вот следующее действие после того, как оператор if закончился, вот это вот действие,
即 if 语句结束后紧接着的下一个操作,
оно в любом случае будет выполнено.
该操作总会被执行。
Конечно, если вот этот вот оператор не подразумевает какого- нибудь фатального
当然,前提是这个语句不涉及任何致命的
действия над программой или какого- то безусловного куда- то перехода.
对程序的操作,或某种无条件的跳转。
В общем, понятна логика, да?
总之,这个逻辑是清楚的,对吧?
Давайте посмотрим на пример на языке программирования.
我们来看一个编程语言中的例子。
Итак, вот программа, в которой я внутри цикла считываю число, и
这是个程序,我在循环中读取一个数字,然后
если остаток определения этого числа на 2 равен нулю, этот оператор сравнения как
如果该数字除以2的余数等于0,这个比较运算符
раз выдаст мне фактически единичку, ну правду, если оно окажется равным нулю.
就会返回1(即真),前提是该余数确实为0。
Вот, ну и в этом случае я говорю, что число isEven, оно чётное.
此时,我声明该数字 isEven(是偶数)。
Давайте запустим, посмотрим на её работу.
我们来运行一下,看看它的执行效果。
Итак. ну например, давайте вот так поставим.
好的,例如,我们这样输入:
Значит, что у нас 10.
那么,我们的输入是10。
Number 10 is even, да?
数字10是偶数,对吗?
Давайте там 5 молчком, 9 молчком, да?
我们来默数:5、9,对吗?
Не знаю, 1000.
不知道,1000。
Number 1000 is even.
数字1000是偶数。
0. Number 0 is zero is even.
0。数字0就是零,它是偶数。
Вот. Ну что? Мы видим, что, во- первых, работает, но есть маленькая ремарка
好了。那么,怎么样?我们看到,首先,程序能运行,但有一个小说明。
о том, как организован цикл.
关于循环的组织方式。
мне не нравится то, как он работает, по той причине, что вообще- то я планировал
我不喜欢它的运行方式,因为实际上我原本计划……
ноль как признак выхода, окончания.
把0作为退出或结束的标志。
Да, вот. А во- вторых, вот здесь вот есть некоторый грязный хак.
对,就是这儿。其次,这里存在一个不太优雅的技巧。
Я сюда специально кладу x, равным единице, чтобы он случайно в качестве мусора не
我特意把x设为1,以免它偶然被当作垃圾数据而变成0。
оказался равным нулю, а это вполне вероятно, вот, и не получилось так, что я вылетел
而这种情况完全可能发生,结果我就没有立刻退出循环。
из цикла сразу.
因此,我并没有立即跳出循环。
Поэтому правильнее было бы вначале считать очередной x, ну, очередной первый x, да,
所以更合理的做法是:先读取下一个x值(即第一个x值),对吧?
а затем, если он не ноль, то сразу проверять, а нечетный ли он.
然后,如果它不为0,就立即检查它是否为奇数。
ну и потом уже считывать следующий на следующую итерацию.
接着再为下一次迭代读取下一个值。
Про вот такой вот формат считывания может быть мы еще с вами поговорим.
关于这种输入格式,我们之后可能还会进一步讨论。
А сейчас давайте, ну во первых можно посмотреть на результат, что теперь у меня он.
现在,我们先来看一下运行结果。
на ноль не реагирует, ноль является просто признаком выхода.
现在程序对输入0不再做出响应,0仅作为退出标志。
Вот, а теперь давайте сделаем альтернативу, то есть" а иначе", да, иначе printf, и
接下来,我们添加一个‘否则’分支,即用else语句,然后调用printf函数。
тут я напишу, соответственно, фразу, что этот number.
这里我将相应地写上这句话:这个number。
в конце точка с запятой, number,
结尾用分号,number,
соответственно, число x, которое какое- то туда вставится, да, из, по, дуду.
即某个数字x,它会被插入到那里,对吧?来自……嗯……随便哪儿。
Всё, ну и теперь на каждое число, которое я буду ему писать, он будет реагировать.
好了,现在,我对每个输入的数字,它都会做出响应。
да? ну пожалуйста, ну там понятное дело, что для тридцатых тоже он как то будет
对吧?好吧,请吧。当然,对于三十几的数,它也会以某种方式响应,
реагировать, да?
对吧?
ну и на ноль просто он выходит.
而遇到零时,它就直接退出。
Так, ну что же, давайте посмотрим, что можно сделать еще интересного при помощи
好了,那么,让我们看看还能借助条件语句做些什么有趣的事情。
условных операторов.
条件语句。
Я могу делать не одно действие.
我可以执行不止一个操作。
Но для этого мне придется, имею в виду действия под условием, придется использовать
但要做到这一点,我的意思是,在条件下的操作,我将不得不使用
фигурные скобки.
花括号。
Фигурные скобки вот при таком простом действии, когда у меня тут один оператор, не
在执行如此简单的操作时(此处仅有一个操作符),花括号
являются обязательными.
并非必需。
Но. Если я хочу вместо оператора вписать сюда блок, да, блок операторов, ну то есть
但是,如果我想在此处用一个操作符块来替代单个操作符——是的,一个操作符块,即
несколько, да, с точками с запятыми друг между другом, то тогда мне обязательно
多个操作符,彼此之间以分号分隔,那么我就必须
придется написать фигурные скобки.
写上花括号。
Надо сказать, что в разных стилях кодирования вот эту фигурную скобку могут затянуть
需要说明的是,在不同的编码风格中,这种花括号可能被移到此处,比如这里加个空格,再跟花括号。
вот сюда, там пробел, фигурная скобка.
那里有个空格,然后是花括号。
Это не имеет никакого значения, язык C это дело игнорирует.
这没有任何影响,C语言会忽略这些。
Здесь, соответственно, что получается?
那么,这里相应地会得到什么?
Else, да, еще второй блок я открываю, да, и здесь пишу столько операторов, сколько
否则,是的,我再打开第二个代码块,是的,然后在这里写入任意数量的语句,
хочу. да то есть не один а много много
我想写多少就写多少,也就是说,不是一个,而是很多、很多。
и возникает интересный вопрос а можно ли можно ли взять и напихать вот сюда вот
这就引出了一个有趣的问题:我们能否在这里,
внутрь еще одно ветвление, еще один условный оператор.
再嵌套一个分支结构,即另一个条件语句?
И туда, и туда.
往这里,也往那里。
А давайте возьмем и поставим такую задачу.
那么,我们来设定这样一个问题吧。
Задачу такую написать несложно.
这个问题写起来并不难。
Эта задача будет у меня про
我的这个问题是关于
четверти на координатной плоскости.
坐标平面上的象限。
来源:Тимофей Хирьянов · CC BY 3.0