第 4 集 · B1 · 7 分钟

C 语言 · 第4集 · 函数是什么

从 Hello World、循环、递归讲到汉诺塔和动态规划,句子短,适合跟读。 开头:C语言中。你们已经见过它们了,我一直在积极使用它们,

C 语言 · 第4集 · 函数是什么

中俄字幕

  1. языке C. Вы их уже видели, я ими активно пользуюсь,

    C语言中。你们已经见过它们了,我一直在积极使用它们,

  2. даже не до конца объяснив, что это такое.

    甚至还没完全解释清楚它们到底是什么。

  3. Что можно вообще делать с функциями?

    函数到底能用来做什么?

  4. Их можно объявить.

    可以声明函数。

  5. определить то же самое, что описать,

    ‘定义’与‘描述’含义相同,

  6. вызвать и еще взять адрес.

    调用函数,以及获取函数地址。

  7. Я не буду работать с адресами функций, это оставим для первого курса.

    我不会讲解函数地址的相关内容,这部分留到大学一年级再学。

  8. вызов функции это самое ходовое.

    函数调用是最常用的操作。

  9. Чтобы функцию вызвать, надо взять, обратиться к ней по ее имени.

    要调用一个函数,需先通过其名称来引用它。

  10. после этого имени написать скобки, и туда поставить какие то фактические значения

    接着在名称后加上括号,并在括号内填入一些实际参数值。

  11. параметров. Между прочим, то, что я говорю фактические значения параметров.

    参数。顺便说一下,我所说的‘实际参数值’。

  12. означает, что у параметров бывают не фактические, а формальные, ну правда не

    意味着参数分为实际参数和形式参数,当然,形式参数并不是真正的值。

  13. значения, а формальные параметры.

    而是形式参数。

  14. То есть список формальных параметров, и мы его видели с вами у функции, которую я

    即形式参数列表,我们之前在定义函数时已见过该列表,它位于函数定义中括号内、以逗号分隔。

  15. создавал, это список, который следует в описании функции через запятую вот в этих

    函数定义中的参数列表,就是函数描述中括号内以逗号分隔的列表。

  16. скобках. определение функции это то же самое что описание функции вот оно

    函数定义与函数描述是同一概念。

  17. В общем виде написано: предполагает тип возвращаемого значения, он должен быть

    一般形式如下:需声明返回值类型,该类型必须在函数描述时已知,且不能是数组。

  18. известен на момент описания функции, и это не может быть массив.

    该类型必须在函数描述时已知,且不能是数组。

  19. это может быть любой из простых типов или пользовательский, вы можете сами создать

    它可以是任意一种基本类型或用户自定义类型。

  20. тип, хотя я про это опять же не рассказывал, как создавать.

    您可自行创建类型,不过我之前并未讲解如何创建类型。

  21. Но, тем не менее, главное, что не массив.

    但最重要的是,它不是数组。

  22. Дальше. Список параметров.

    接下来是参数列表。

  23. А, прошу прощения, имя.

    啊,抱歉,是名称。

  24. должно быть латинскими буквами, цифрами и знак подчёркивания.

    名称只能包含英文字母、数字和下划线。

  25. Никакие другие символы недопустимы: ни значки плюс- минус там и так далее, ни

    其他任何字符都不允许:例如加号、减号等符号,以及

  26. русскоязычные и прочие язычные символы.

    俄文及其他语言的字符。

  27. Имя должно быть непрерывным, без пробелов.

    名称必须是连续的,不能包含空格。

  28. Если вы хотите разделить несколько слов, используйте знак подчёркивания.

    如果想分隔多个单词,请使用下划线。

  29. Его специально разрешили в именах функций, ну и у переменных то же самое.

    下划线被特别允许用于函数名,变量名也同样适用。

  30. Далее, в списке параметров следуют они точно так же, как описываются переменные в

    接下来,在参数列表中,它们的写法与变量声明完全相同。

  31. теле функции, то есть тип имя, тип имя.

    函数的参数,即类型 名称、类型 名称。

  32. Вот эти имена формальные— это то, под каким именем переменная будет жить внутри

    这些名称是形式参数——即变量在函数内部所使用的名称。

  33. функции. То есть пока выполняется ее тело, мы будем доступаться к этому параметру

    也就是说,在函数体执行期间,我们将通过这个参数名来访问该参数。

  34. именно по этому имени.

    也就是说,在函数体执行期间,我们将通过这个参数名来访问该参数。

  35. ну можно сказать, вряд ли вы это поймете, что параметры передаются в функцию все по

    嗯,可以说,你可能不太容易理解:所有参数都是按值传递给函数的。

  36. значению. Давайте двинемся дальше.

    我们继续往下讲。

  37. Функции бывают вызываемы синхронно и асинхронно.

    函数可以同步调用,也可以异步调用。

  38. Что это значит?

    这是什么意思?

  39. что у вас идет поток исполнения, то есть началась ваша программа, да, и пошел

    你的程序有一个执行流,即程序启动后,主执行流就开始运行。

  40. основной поток исполнения, пошла функция main, да, пошли команды, вот они идут,

    主执行流进入 main 函数,然后依次执行各条指令。

  41. идут, идут, и вот тут вот раз и вызов функции.

    程序在运行,运行,然后在这里突然就调用了函数。

  42. Да? Что происходит в момент вызова функции?

    是吗?函数被调用的那一刻,发生了什么?

  43. Возможно два варианта.

    可能有两种情况。

  44. Представьте себе, что вы вызываете сантехника и говорите ему: отремонтируй ванну.

    想象一下,你打电话叫来一位水管工,对他说:‘请修好浴缸。’

  45. Сантехник начинает ремонтировать ванну, для него началось исполнение.

    水管工开始修理浴缸,对他来说,工作就此开始了。

  46. То есть там функция main вызвала функцию а, и функция а пошла выполнять свои

    也就是说,主函数main调用了函数a,而函数a就开始执行自己的

  47. команды. Вот она пошла, выполняет их.

    指令。它就这样出发了,正在执行这些指令。

  48. Но а что основная функция?

    那么主函数呢?

  49. Она как? Она стоит и молча ждет или продолжает свое выполнение?

    它处于什么状态?是站在那儿默默等待,还是继续执行自己的任务?

  50. ну если она просто продолжает свое выполнение, тогда большой вопрос, а зачем же она

    如果它只是继续执行自己的任务,那就有个大问题:它何必还要调用这个函数呢?

  51. эту функцию вызывала?

    调用这个函数了吗?

  52. ну логично, чтобы получить какой- то результат.

    嗯,这很合理,这样才能得到某个结果。

  53. может быть вот такой результат, в смысле x равно значению функции, да?

    结果可能是这样,即x等于该函数的返回值,对吗?

  54. то есть, но это. . .

    也就是说,但这……

  55. тогда мы не можем продолжить, пока функция а не закончится, понимаете?

    那么,在函数A执行完毕之前,我们就无法继续,明白吗?

  56. то есть значит так.

    也就是说,情况是这样的。

  57. Существуют асинхронные вызовы, когда функция А работает, а главная функция

    存在异步调用,即函数A在运行时,主函数

  58. продолжает работать, да, и они работают параллельно.

    继续运行,对吧?它们是并行执行的。

  59. Это относится к области параллельного программирования.

    这属于并行编程领域。

  60. Вполне возможно, что функция А вызовет еще какую- нибудь функцию Б, они будут тоже

    函数A很可能还会调用另一个函数B,它们也会

  61. выполняться параллельно.

    并行执行。

  62. У меня возникают уже три нити исполнения.

    我已经产生了三个执行线程。

  63. Я могу загрузить процессор, в котором там три ядра.

    我可以充分利用一个拥有三个核心的处理器。

  64. В какой- то момент функция main говорит: а теперь мне нужен результат.

    在某个时刻,main函数表示:‘现在我需要结果了。’

  65. То есть я вот, как сказать, ходил- ходил мимо ванной, а теперь мне нужно руки

    也就是说,我之前一直路过洗手间,但现在需要洗手。

  66. помыть. Да, и вот она ждет, и дальше не может продолжить свою жизнь, пока руки не

    是的,于是它开始等待,且无法继续后续操作,直到双手被洗净。

  67. будут помыты. И поэтому она ждет, пока функция А закончит окончательно.

    因此,它会一直等待,直到函数A彻底执行完毕。

  68. Да? Функция А в какой- то момент заканчивает свое выполнение и возвращается сюда,

    对吗?函数A在某个时刻结束执行,并返回到这里。

  69. да, и можно продолжать.

    是的,之后就可以继续执行了。

  70. Функция main просыпается и продолжает свое выполнение.

    main函数被唤醒,并继续执行。

  71. я рассказываю про это заранее, чтобы вы не были шокированы, когда у вас будет

    我提前说明这一点,以免你们在遇到这种情况时感到震惊。

  72. параллельное программирование.

    并行编程。

  73. там возможно вот необходимо это как то синхронизировать уметь дожидаться этого

    这里可能需要进行某种同步,即能够等待该操作完成。

  74. асинхронного вызова.

    异步调用。

  75. В случае обычного языка C, когда нет параллельного программирования, у нас вызовы

    在普通的C语言中,如果没有并行编程,所有函数调用都是同步的。

  76. синхронные. Это значит, что с того момента, когда функция main позвала функцию а, до

    这意味着,从主函数(main)调用函数a那一刻起,直到函数a执行完毕并返回,

  77. момента, пока функция а не сделает return, пока она не закончит свое выполнение,

    函数a未返回之前,主函数将一直休眠。

  78. функция main спит беспробудно.

    主函数会持续深度休眠。

  79. то же самое происходит и с функцией а.

    函数a的情况也是一样。

  80. В то время, если она позвала функцию b, из функции а вызывается функция b, да, вот

    例如,当函数a调用函数b时,函数b便从函数a中被调用,是的,就是这样。

  81. она вызвала, и спит себе.

    她调用了,然后自己睡着了。

  82. Понятно? То есть исполнение у нас вот в этот момент вот тут вот оно приостановлено.

    明白了吗?也就是说,此刻我们的执行就在这里暂停了。

  83. То есть оно уже получается как бы дважды приостановлено: и это, и это, оно стоят оба

    也就是说,它实际上被暂停了两次:这个和这个,两者都处于暂停状态。

  84. ждут. Теперь помощник сантехника, грубо говоря, работает, да?

    现在,粗略地说,水管工助手正在工作,对吧?

  85. А помощник сантехника вызывает, не знаю, там, допустим, крысу свою, да, чтобы она

    而水管工助手又调用——我不知道,比如说——她自己的老鼠,让它……

  86. проползла по трубе.

    沿着管道爬过去。

  87. Ну вот, как в сказке про репку, да, мышка действует самостоятельно, крыска действует

    就像《拔萝卜》的童话故事一样,对吧?小老鼠独立行动,小老鼠也独立行动……

  88. самостоятельно, она заканчивает свое выполнение, никого не вызывает.

    独立行动,它完成自己的任务,不再调用任何人。

  89. Да, иначе бы это дело продолжалось бесконечно.

    是的,否则这事就会无限进行下去。

  90. То есть я специально вот так вот нарисую, да, что вот эта функция, прошу прощения, B

    也就是说,我特意这样画出来——抱歉,这个函数叫B。

  91. ожидает, а C выполнилась и вернула исполнение к B.

    正在等待,而C已执行完毕并将控制权交还给B。

  92. B заканчивает, A дождалась результата, доделала то, что должна была сама доделать, и

    B执行完毕,A等待到了结果,完成了自身需要完成的工作,然后

  93. вернула исполнение main.

    将控制权交还给main函数。

  94. Понятно? То есть они все спят, и одновременно работает только одна функция.

    明白了吗?也就是说,它们都在休眠,同一时间只有一项函数在运行。

  95. Но вот это сонное ожидание.

    但这种休眠式等待

  96. оно существует.

    是真实存在的。

  97. Есть еще один интересный момент.

    还有一个有趣的细节。

来源:Тимофей Хирьянов · CC BY 3.0

同系列