2024 - Введение в Программирование - CS50 - Язык C (Часть 1)
Table of contents
- Обучение программированию должно быть доступно каждому, и я создал уникальный курс, чтобы вы могли начать свой путь в IT уже сегодня.
- Переход от написания исходного кода к машинному коду упрощается с помощью компилятора, который делает программирование доступным и понятным.
- Переход на интерфейс командной строки может сделать вас более продуктивным и эффективным программистом.
- Не используйте пробелы в именах файлов и держите всё в нижнем регистре, чтобы облегчить жизнь в командной строке.
- Не ставьте Enter в середине строки кода, языки программирования это не любят.
- Библиотеки в программировании — это код, написанный кем-то другим, который вы можете использовать, чтобы не изобретать велосипед.
- Интерфейс может показаться сложным, но со временем станет понятнее.
- Программирование на C требует больше внимания к деталям, но это помогает лучше понять, как работает память компьютера.
- В программировании важны детали: даже запятая может изменить смысл кода.
- Понимание основ программирования сейчас облегчит изучение других языков в будущем.
- Чтобы компилятор распознал функцию, включите соответствующий заголовочный файл.
- Используйте фигурные скобки даже для одной строки в условных операторах, чтобы код был понятнее и напоминал визуальные блоки Scratch.
- Оптимизируйте свой код, чтобы не тратить время компьютера и свои ресурсы впустую.
- Программирование — это как создание блок-схемы, где каждое условие ведет к новому результату.
- Оптимизация кода — это не только о правильности, но и об эффективности.
- Оптимизируйте код, чтобы избежать ненужных проверок и повысить безопасность.
- Учись программировать с нуля и создавай свои веб-приложения с искусственным интеллектом!
Обучение программированию должно быть доступно каждому, и я создал уникальный курс, чтобы вы могли начать свой путь в IT уже сегодня.
Обучение в IT должно быть доступно каждому, и именно поэтому я создал уникальный курс для тех, кто хочет освоить программирование с нуля. Этот курс предлагает полный набор базовых знаний: от решения задач и структур данных до алгоритмов и баз данных. Обучение сразу двум популярным языкам, Python и JavaScript, понимание работы веба и создание собственного веб-приложения с искусственным интеллектом. Практические советы по развитию карьеры и поиску работы основаны на моём личном опыте в индустрии. Наш курс представлен на трёх уровнях объяснения: если что-то непонятно на одном уровне, переходите на следующий, где материал изложен ещё проще. Такой подход вы больше нигде не встретите. И самое главное, курс стоит в десятки раз дешевле аналогичных программ от раскрученных школ и станет отличной инвестицией в ваше будущее. Ссылка на курс с весомой скидкой в описании под видео. Присоединяйтесь и начните свой путь в IT уже сегодня.
А теперь перейдём к курсу CS50 и первой неделе, так сказать, с нулевым индексом. Сегодня мы разберём более традиционный и старый язык под названием C. Будьте уверены, что даже если то, что вы сегодня увидите, выглядит очень загадочно и необычно, особенно если вы среди тех, кто менее уверен, держитесь за идеей из прошлой недели, где мы обсуждали основы функции, циклы и условия, которые сегодня вновь к нам вернутся. На прошлой неделе и в наборе задач номер ноль мы сосредоточились на обучении программированию с помощью Scratch, с которым вы, возможно, играли в молодости. Сегодня мы сосредоточимся на языке C, но по пути мы также будем учиться решать проблемы.
Цель на сегодня и на весь курс — давать вам неделю за неделей всё больше инструментов для вашего инструментария, с помощью которых можно решать задачи. Например, сегодня мы узнаем, как всё больше и больше решать задачи с помощью функций, переменных, условий, циклов и многого другого. Но мы также узнаем, как такие задачи решать не надо. Оказывается, как бы ни были мощны компьютеры, Mac, ПК, сотовые телефоны в наши дни, есть определённые вещи, которые они не могут делать очень хорошо, и информация, которую они не могут представить очень хорошо. Это приводит ко многим реальным проблемам как в прошлом, так и в будущем.
Итак, больше о том, что мы не сможем сделать с помощью программирования, мы обсудим в ближайшее время. Но помимо этого, давайте вернёмся к этой картинке. Это была самая первая программа, которую я написал, и которую вы, вероятно, также написали в какой-то форме. Всё, что она делает, это говорит "Hello, world". Как и было обещано, сегодня этот фрагмент головоломки или эти фрагменты головоломки вместе довольно быстро начнут выглядеть более понятными. Я намеренно раскрасил его таким образом, чтобы текст на экране теперь напоминал элемент головоломки.
Если я вернусь назад, обратите внимание, что у нас был этот элемент головоломки, когда кликаешь на зелёный флаг, который запускает весь процесс. Как только вы нажмёте кнопку в правом верхнем углу пользовательского интерфейса Scratch, появляется фиолетовый блок, который является глаголом, действием, функцией, которая что-то делает. Итак, если я снова вернусь к тому, что мы собираемся разобрать сегодня, на экране будет какой-то стандартный текст, какой-то оранжевый текст, который пока что мы просто вводим и принимаем как должное, как будто вам нужно писать код именно так. Но более интересным будет фиолетовый цвет, и сегодня мы увидим, что функция, которая раньше называлась say в Scratch, теперь называется Print F в языке C. На белом цвете вы увидите текст, похожий на белый овал на прошлой неделе, где фактически может быть ввод пользователя, например ваш ввод как программиста.
Есть много отвлекающих факторов, и честно говоря, именно такие вещи обычно отвлекают и даже расстраивают в начале обучения программированию в первый раз. Но идеи, что наиболее важно, будут теми же самыми. Так как же мы собираемся это использовать? Оказывается, как и на прошлой неделе, вы начнёте писать то, что называется исходным кодом. Код, как мы его знаем, более технически называется исходным кодом, это то, что вы и я, то есть люди, на самом деле пишем.
Переход от написания исходного кода к машинному коду упрощается с помощью компилятора, который делает программирование доступным и понятным.
Сегодня мы увидим, что функция, которая раньше называлась say Scratch, теперь называется Print F в языке под названием C. На белом фоне вы увидите текст, похожий на белый овал, как на прошлой неделе, где может быть ввод пользователя, например, ваш ввод как программиста. Есть много отвлекающих факторов, и честно говоря, именно такие вещи обычно отвлекают и даже расстраивают в начале обучения программированию. Но идеи, что наиболее важно, будут теми же самыми.
Как же мы собираемся это использовать? Оказывается, как и на прошлой неделе, вы начнёте писать то, что называется исходным кодом. Код, как мы его знаем, более технически называется исходным кодом. Это то, что вы и я, то есть люди, на самом деле пишем. Действительно, это может выглядеть примерно так, как мы только что видели. Но, к сожалению, компьютеры говорят только на двоичном языке нулей и единиц, более известном как машинный код. Другими словами, те же самые паттерны нулей и единиц, как на прошлой неделе. Кто-то предложил, что они выводят Hello, world на экран, потому что один из этих паттернов - это H, другой шаблон - это e, и так далее. Также и другие паттерны этих нулей и единиц являются командами или инструкциями для компьютера, которые буквально говорят: "Покажи мне Hello, World на экране".
Писать машинный код было бы не так весело, если бы он действительно был из нулей и единиц. К счастью, вы и я будем писать исходный код, который концептуально находится на высоком уровне. Но нам понадобится программа для преобразования его в низкоуровневый машинный код, чтобы мы не тратили свою жизнь на чтение и написание нулей и единиц. В прошлом это делалось с помощью перфокарт и отверстий на физических листах бумаги, но уже ушли от этого. После многих лет инноваций люди дали нам языки более высокого уровня.
Итак, вот что нам нужно будет сегодня сделать. Если в конце концов мы с вами пишем исходный код, но хотим получить на выходе машинный код, нам нужно что-то посередине, что будет преобразовывать этот исходный код в машинный код. Нам с вами не придётся учить или даже вообще говорить о нулях и единицах. Тип программы, которую мы начнём использовать сегодня и познакомимся с ней, называется компилятор. Компилятор - это программа, которая переводит один язык в другой. Это могут быть любые два языка, но сегодня и вообще мы будем говорить о нём в контексте перевода исходного кода в машинный код. По сути, Apple, Google, Microsoft или люди из других компаний, или даже волонтёры написали программное обеспечение, которое выполняет эти преобразования. Вы и я по сути собираемся загрузить бесплатный компилятор и использовать его, чтобы наш компьютер понимал исходный код, который мы с вами пишем на этих языках более высокого уровня.
Где же мы будем это делать? Мы могли бы дать вам инструкции, и вы могли бы загрузить соответствующее бесплатное программное обеспечение с открытым кодом на свой Mac или ПК. Но реальность такова, что это создаёт много технических проблем, потому что у всех у нас немного разные компьютеры, немного разные версии Windows, macOS, Linux или других операционных систем. Это тоже как правило отвлекает внимание в начале любого подобного курса или обучения программированию. Поэтому вместо этого мы будем использовать облако. Мы будем использовать URL-адрес csd, который поместит в окно вашего браузера абсолютно всё, что вам нужно для курса. Мы будем использовать программное обеспечение под названием Visual Studio Code (также известное как VS Code), которое само по себе является бесплатным и очень популярным в отрасли. Это то, что настоящие программисты используют каждый день. Однако это его облачная версия, и поэтому всё будет просто работать для вас из коробки.
К концу cs50 цель будет состоять в том, чтобы снять вас с инфраструктуры C, чтобы вы могли загрузить это свободное доступное программное обеспечение на свой Mac или ПК. Совсем скоро я сам перейду по этому URL-адресу на своём компьютере, и вы увидите пользовательский интерфейс, который выглядит примерно так. Цвета могут отличаться в зависимости от ваших настроек, шрифты тоже могут отличаться, но в целом он состоит из нескольких разных частей. Здесь вверху мы сегодня начнём писать код. Это интерфейс с вкладками, как и во многих программах в наши дни. Это тот же самый код на C, который мы видели совсем недавно. Здесь внизу находится то, что мы будем называть окном терминала или консолью. Окно терминала - это то место, где мы будем вводить команды для компиляции нашего кода, то есть для запуска нашего кода. Сегодня мы увидим контраст между графическим пользовательским интерфейсом и командной строкой.
Переход на интерфейс командной строки может сделать вас более продуктивным и эффективным программистом.
Итак, совсем скоро я сам перейду по этому URL адресу на своём компьютере, и вы увидите пользовательский интерфейс, который выглядит примерно так. Цвета могут отличаться в зависимости от ваших настроек, шрифты тоже могут отличаться, но в целом он состоит из нескольких разных частей. Вверху мы начнём писать код. Это интерфейс с вкладками, как и во многих программах в наши дни, и это тот же самый код на C, который мы видели совсем недавно. Это то место, где через мгновение я начну его вводить.
Внизу находится то, что мы будем называть окном терминала или консолью. Окно терминала - это то место, где мы будем вводить команды для компиляции нашего кода, то есть для запуска нашего кода. Сегодня мы увидим контраст между графическим пользовательским интерфейсом (GUI), который имеет меню, значки, элементы, по которым вы щелкаете, и командной строкой (CLI). Мы будем использовать оба этих интерфейса вместе. Интерфейс командной строки означает, что здесь внизу вы используете только клавиатуру. Вы можете также щёлкать мышью, если хотите, но это, как правило, не даст большого эффекта, потому что интерфейс командной строки принимает команды с клавиатуры.
В каком-то смысле это будет похоже на шаг назад от компьютеров Mac, ПК, iPhone и Android, которые у всех у нас и которые в основном графические. Однако, когда вы становитесь более опытным пользователем или программистом, вы можете быть намного более продуктивным и эффективным, научившись использовать интерфейс командной строки и используя оба типа интерфейсов для того, что каждый из них делает хорошо.
Слева вы скоро увидите интерфейс папок, как в macOS или Windows, где будут находиться любые файлы или папки, которые мы создаём в CS50. Это даёт вам лучшее из обоих миров: вы можете указывать и щёлкать слева и вводить команды внизу. Вот код, который я предлагаю нам написать в первую очередь, точно так же, как мы написали нашу самую первую программу в Scratch, чтобы сказать "Привет, мир". Давайте сделаем именно так. Я собираюсь переключиться на этот экран, где я уже вошёл в CS50 Dev на своём компьютере. Чтобы сосредоточиться на коде, я скрыл панель активности и проводник.
Вы видите здесь область, где будут размещены все мои вкладки и окно терминала, куда будут вводиться все мои команды. Я упростил пользовательский интерфейс, чтобы сосредоточить ваше внимание на интересных частях. Как мне на самом деле написать, скомпилировать и запустить код? Будут эти три шага. Одна из этих команд называется, как и следовало ожидать, Code. Code просто позволит мне открыть или создать новый файл, например, файл под названием h.c. Make будет пока что моим компилятором, который позволяет мне создавать программу, то есть преобразовывать исходный код в машинный код от C до нулей и единиц. Затем Hello будет командой для запуска моего фактического кода, то есть текстовым эквивалентом двойного щелчка по значку на Mac или ПК или нажатия на значок на вашем телефоне.
Эти три команды позволят мне в конечном итоге писать, компилировать и запускать код. Давайте сделаем это. Я вернулся в свой интерфейс VS Code. Я собираюсь запустить Code h.c. и обратить внимание на пару деталей. Во-первых, есть этот странный знак доллара, который не имеет ничего общего с деньгами. Это просто общепринятое соглашение в мире программирования для представления вашей командной строки. Если я когда-нибудь скажу "перейдите к вашей командной строке", я имею в виду "перейдите в окно терминала".
Теперь, когда я набрал код пробел h.c., и точно так же, как документы Word имеют своё собственное расширение файла, например, docx, файлы C имеют расширение файла по соглашению, которое является .c. Пара мелких замечаний: по соглашению я почти всегда буду называть свои файлы в нижнем регистре, я никогда не буду использовать пробелы в именах файлов, и моё расширение файла тоже будет в нижнем регистре. Случайное нажатие клавиши пробела или использование имён файлов с пробелами просто усложняет жизнь, когда вы находитесь в командной строке.
Мой курсор буквально мигает, потому что программа хочет, чтобы я написал какой-то код. Я сделаю это по памяти. Вам, вероятно, потребуется некоторое время, чтобы приобрести такие же инстинкты, но я собираюсь набрать эту первую строку здесь, начиная с include.
Не используйте пробелы в именах файлов и держите всё в нижнем регистре, чтобы облегчить жизнь в командной строке.
По соглашению, я почти всегда буду называть свои файлы в нижнем регистре. По конвенции, я никогда не буду использовать пробелы в именах файлов, и моё расширение файла тоже будет в нижнем регистре. Короче говоря, случайное нажатие клавиши пробела или использование имён файлов с пробелами просто усложняет жизнь, когда вы находитесь в командной строке.
Итак, мой курсор буквально мигает, потому что программа хочет, чтобы я написал какой-то код. Я сделаю это по памяти. Вам, вероятно, потребуется некоторое время, чтобы приобрести такие же инстинкты, но я собираюсь набрать эту первую строку здесь, начиная с include. Обратите внимание, что то, что должно произойти здесь, достаточно интересно в коде, который я хочу набрать. Я хочу использовать то, что мы назовём фигурными скобками, своего рода ками, которые вы не часто используете в английском языке, но они есть где-то на вашей клавиатуре.
Обратите внимание, что делает весь код и многие среды программирования. Он заканчивает часть моей мысли. Итак, я собираюсь набрать только левую фигурную скобку, но обратите внимание, что я на самом деле получаю две из них. Если я нажму Enter, заметьте, что он не только немного сдвинул одну вниз, но и сделал отступ для моего курсора. Точно так же, как и с псевдокодом на прошлой неделе, всякий раз, когда вы делаете что-то логически, что должно происходить только если происходит то, что выше него, аналогично отступ будет актуален, когда мы на самом деле пишем код. Таким образом, VS Code и подобные программы просто пытаются сэкономить нам нажатие клавиш, чтобы мне не приходилось тратить время на нажатие клавиши пробела или Tab.
С учётом сказанного, я собираюсь набрать последнюю из этих строк - printf, где F будет означать отформатированный, а затем круглые скобки. Обратите внимание, что он дал мне две скобки. Он дал мне вторую бесплатно. Иногда он может запутаться, и вы, конечно, можете переопределить их, удалить их и начать заново. Теперь, в отличие от Scratch, в C оказывается, что мне нужно будет использовать двойные кавычки всякий раз, когда я использую английское слово или фразу, или любой человеческий язык. Например, "Hello, World", а затем в самом конце строки, подобно тому как в английском языке используются точки, в C я буду использовать точку с запятой.
Итак, много разговоров, но не так много программирования. Технически это шесть строк кода, но честно говоря, единственное интересное - это строка printf. Это эквивалент того блока say. Теперь постучим по дереву, надеюсь, что я не сделал никаких опечаток. Код автоматически сохранится. Я вернусь в окно терминала, где теперь выполню вторую команду - make hello. Вы не говорите make hello.com. Он будет искать в моей папке. Если он увидит файл с именем hello.com, код для создания файла make для компиляции файла из исходного кода в машинный код, и последняя - это ./hello. Итак, это теперь эквивалентно двойному щелчку на Mac или ПК, или одиночному нажатию на телефоне. Enter.
Так, близко. Хорошо, это довольно неплохо. Я получил "Hello, World", но в моём выводе есть что-то немного глупое, что может раздражать некоторых из вас в эстетическом плане. Да, знак доллара выглядит так, как будто я написал "Hello, World" со знаком доллара в моём выводе, но нет, это просто своего рода остаток моей командной строки, начинающейся со знака доллара. Это немного придирчиво, но это просто не кажется правильным, не выглядит правильно, это не совсем верно.
Итак, как я могу исправить это? Здесь, по крайней мере поначалу, потребуется некоторое знакомство с новым синтаксисом C, чтобы это исправить. Инстинктивно мы можем сделать что-то вроде этого. Позвольте мне просто нажать Enter вот так. Но это должно вскоре, если ещё не сейчас, вызвать у вас неприятное ощущение, потому что в целом мы увидим, что программирование на C и на Python и на других языках как правило основано на строках. То есть вы действительно должны начинать и заканчивать свою мысль на одной строке. Так что если у вас есть привычка нажимать Enter вот так и заканчивать свою мысль на следующей строке, языки программирования как правило этого не любят. Так что это на самом деле не даст нам ожидаемого результата.
Чтобы показать вам это, я сделаю следующее. Позвольте мне вернуться к терминалу. Здесь я снова запущу make hello после внесения этого изменения. Enter, и вот он первый наших ошибочных выводов. Он кричит на меня: "отсутствует завершающий символ". Здесь есть немного красного, немного зелёного, который привлекает моё внимание. Иногда эти сообщения об ошибках будут простыми, иногда вам придётся поломать голову, чтобы разобраться в них. Но пока я как бы это испортил.
Не ставьте Enter в середине строки кода, языки программирования это не любят.
Вы действительно должны начинать и заканчивать свою мысль на одной строке. Если у вас есть привычка нажимать Enter и заканчивать свою мысль на следующей строке, языки программирования, как правило, этого не любят. Это не даст нам ожидаемого результата. Чтобы показать это, я сделаю следующее: вернусь к терминалу и снова запущу Make Hello после внесения этого изменения. Вот он, первый из наших ошибочных выводов, и он кричит на меня, что отсутствует завершающий символ. Здесь есть немного красного и зелёного, что привлекает моё внимание. Иногда эти сообщения об ошибках будут простыми, иногда придётся поломать голову, чтобы разобраться в них. Очевидно, что Enter - это неправильное решение.
Оказывается, обратная косая черта N будет своего рода волшебным способом обеспечить получение новой строки в конце вывода. Позвольте мне снова запустить Hello, потому что я изменил свой код. Мне нужно снова преобразовать и перекомпилировать исходный код. Вот она, каноническая программа Hello world, которую я надеялся написать с самого начала. Пока не беспокойтесь об include, Standard IO, int, Main, Void или фигурных скобках. Сосредоточьтесь в первую очередь на строке пять. В течение сегодняшнего и следующего дня мы начнём разбирать остальные символы, которые пока вы должны принимать за чистую монету.
Если есть вопросы по любому из этих шагов, которые мы только что сделали, например, почему обратная косая черта N находится внутри кавычек, короткий ответ заключается в том, что это просто то место, где она должна быть. Внутри кавычек находятся входные данные, которые вы хотите, чтобы Print F выводил на экран. Если вы хотите, чтобы Print F - это функция - вводила новую строку, она должна быть включена в текст кавычек, которые вы ей даёте. Обратная косая черта N - это специальный паттерн для printf, означающий, что нужно переместить курсор на следующую строку.
Если вы хотите напечатать обратную косую черту N, тут всё становится немного сложнее. Оказывается, в программировании, когда вы хотите, чтобы появился буквальный символ, вы ставите ещё одну обратную косую черту перед ним. Это не то, что мы будем делать часто, но на самом деле есть решение этой проблемы.
Теперь сравним это с тем, что мы уже сделали. Вот первая программа Scratch, которую мы написали с зелёным флагом. Напомню, представлена ментальная модель, которую я предложил для почти всего, что мы делаем, где функции - это просто реализация алгоритмов, пошаговых инструкций для решения задач. Входные данные для функций называются аргументами или параметрами. Иногда функции могут иметь побочные эффекты, как в прошлый раз со сч, когда диалоговое окно волшебным образом появлялось рядом с ртом кота как своего рода побочный эффект от использования блока say.
Сравнивая слева направо, блок say в Scratch и код C, обратите внимание на пару вещей. Print - это почти имя функции, технически это printf по причинам, которые мы в конечном итоге увидим. Скобки в C вызывают в памяти овал в Scratch. Вероятно, именно поэтому MIT выбрал овал, потому что многие языки используют скобки таким образом. Вы всё ещё пишете Hello world, как мы уже делали на прошлой неделе в Scratch. Однако, как вы могли увидеть в нашей демонстрации, вам действительно нужны двойные кавычки, а не одинарные, и для того чтобы получить новую строку, вам нужна обратная косая черта N. Также нужна точка с запятой, чтобы закончить мысль.
Все эти глупые вещи, которые вы изначально забудете, если никогда раньше не программировали, вскоре разовьются в мышечную память. Обратная косая черта N обычно известна как Escape последовательность и позволяет указать символ, который в противном случае было бы трудно набрать. Давайте разберём некоторые другие вещи, которые уже находятся над этой функцией. In CL sdo оказывается, что в C большая часть функциональности предоставляется...
Библиотеки в программировании — это код, написанный кем-то другим, который вы можете использовать, чтобы не изобретать велосипед.
Для того чтобы использовать двойные кавычки вместо одинарных, нужно поставить двойные кавычки слева и справа. Чтобы получить новую строку, вам нужна обратная косая черта N. Также отсутствует точка с запятой, чтобы закончить мысль. Все эти глупые вещи, честно говоря, вы изначально забудете, если никогда раньше не программировали. Но вскоре, в течение дней или недель, разовьётся мышечная память.
Обратная косая черта N обычно известна как Escape последовательность. Она позволяет указать символ, который в противном случае было бы трудно набрать. Давайте разберём некоторые другие вещи, которые уже находятся над этой функцией. В языке C большая часть функциональности спрятана в отдельных файлах. Поэтому, если вы хотите использовать определённые функции, вы должны сказать компилятору: "Эй, я хочу выполнить некоторый стандартный ввод и вывод". Например, если вы хотите напечатать что-то на экране, вам нужно использовать Print F.
Файл sdo по сути содержит объявление для Print F, которое научит компилятор выводить что-то на экран. Команда include здесь просто говорит компилятору найти на локальном жёстком диске файл с именем sdo и скопировать или вставить его туда, чтобы теперь компилятор знал о Print F. Этот файл, который мы будем называть титульным файлом, представляет собой библиотеку. Библиотека в мире программирования - это код, который написал кто-то другой и который вы можете использовать. Обычно он бесплатный и с открытым исходным кодом, что означает, что вы можете буквально увидеть код, который написал кто-то другой. Иногда вы платите за него, и он может быть закрытым исходным кодом, как у Microsoft.
Библиотеки очень полезны, потому что, честно говоря, даже я не совсем понимаю, как работает Print F. Я принимал как должное в течение 25 лет, что если я использую Print F, то на экране что-то печатается. Но кто-то умнее меня должен был фактически написать код на C, который выясняет, как получить "Hello" и так далее. Таким образом, библиотеки позволяют нам стоять на плечах гигантов, решая проблемы, которые для нас более интересны.
Титульный файл C - это просто файл, заканчивающийся на .h, который даёт вам доступ к библиотеке. В мире программирования есть так называемые справочные страницы - текстовые файлы, своего рода документация, через которую вы можете узнать, как работает функция или как вы можете использовать её входные данные или аргументы. Реальность такова, что они написаны для людей, которые уже долгое время программируют, и поэтому их немного сложно понять для новичков.
CS50 имеет свою собственную версию справочных страниц по URL адресу Manual cs50.io, где вы увидите не только официальную документацию для C, но и упрощения, написанные персоналом на общедоступном языке. Это представляют собой различные популярные функции, их входные и выходные данные. Например, в разделе std вы можете фактически увидеть документацию для Print F.
Перейдя на Manual cs50.io, вы увидите интерфейс, который на первый взгляд может показаться немного ошеломляющим, но он будет выглядеть всё более и более знакомым со временем. В разделе synopsis вы увидите, что если хотите использовать Print F, вам нужно включить титульный файл. Вы буквально копируете и вставляете эту строку в свой код. Также вы увидите подсказку о том, как будет выглядеть функция. Более важно, вы можете прочитать описание, написанное преподавателями и ассистентами курса, которое будет гораздо более доступным для понимания.
Интерфейс может показаться сложным, но со временем станет понятнее.
Интерфейс, который на первый взгляд может показаться немного ошеломляющим, будет выглядеть всё более и более знакомым со временем. Во-первых, здесь вы можете увидеть, что если вы хотите использовать Print F, в разделе synopsis вам нужно включить этот титульный файл. То есть, вы буквально копируете и вставляете эту строку в собственный код. Вы также увидите, что пока немного загадочно, но это тоже своего рода подсказка о том, как будет выглядеть функция. Но об этом чуть позже.
Более важно, вы можете прочитать об этом в описании, поскольку эти описания, когда вы находитесь в менее комфортном режиме, написаны мной и преподавателями курса, ассистентами преподавателей, ассистентами курса. Вы найдёте их гораздо более доступными для понимания. Поэтому, если коротко, полагайтесь на этот сайт, когда захотите узнать, как использовать какую-то функцию, а также какие-то другие функции, которые у нас существуют. На самом деле, если я вернусь на главную страницу, то вы увидите, что есть все эти функции, которые часто используются в CS50, и есть ещё сотни других, которые поставляются с C.
Изучение языка программирования заключается не в изучении всех этих функций, а скорее в том, чтобы получить представление о том, где вы найдёте ответы на вопросы, когда захотите попробовать что-то новое. Но что важно знать для CS50 сегодня, так это то, что у нас есть свой собственный титульный файл под именем CS, который содержит функции, которые мы написали только для того, чтобы облегчить жизнь в первые несколько недель занятий. Это так называемые учебные колёса, которые мы в конце концов снимем со своего велика.
Оказывается, что C, особенно если вы программировали раньше, на самом деле очень сложно получать ввод от пользователя, заставлять их вводить слово или что-то ещё. Как будто C специально не делали лёгким, отчасти потому что это один из первых языков, который не был сделан только из нулей и единиц. Так что вам приходится делать много тяжёлой работы самостоятельно. Но сегодня, на несколько недель, мы наденем эти учебные колёса, чтобы мы могли сосредоточиться на интеллектуально интересных идеях C и программировании в целом, не увязая в определённых сорняках, к которым мы вернёмся в ближайшее время.
Например, собственная документация CS находится по этому URL адресу. В библиотеке есть функции, такие как Get string для получения текстовой строки (string - это синоним простого текста в языке программирования). Таким образом, Get string предложит человеку ввести текстовую строку. Get int - это сокращение от Get integer, если вы хотите получить целое число от пользователя. Get float немного более загадочен, он позволяет получить число с плавающей запятой, например, действительное число с десятичной точкой в нём и так далее.
Это значит, что в CS50 у нас есть некоторые удобные для пользователя функции, с помощью которых мы можем фактически получить некоторый ввод. Давайте используем одну из этих наших функций, например Get string. Напомню, на прошлой неделе наша вторая программа в Scratch была такой, где мы не просто говорили "Hello world", мы говорили "Hello David" или "Hello Carter" или "Hello", кто бы не вводил своё имя. Для этого нам нужен был блок Ask в Scratch, затем мы использовали блок Save и затем блок Join, чтобы всё это работало.
Теперь давайте переведём эту программу на C, потому что она немного более интересная и показательна для того типа кода, который мы начнём писать. Нам нужна немного другая ментальная модель. У нас всё ещё есть функция, которая является реализацией алгоритма в коде. У нас есть ещё некоторые входные данные, называемые аргументами. Ранее я говорил, что блок say и в свою очередь Print F имеют побочные эффекты, которые представляют собой просто что-то визуальное, что обычно происходит на экране.
Другие функции на самом деле имеют то, что мы называли на прошлой неделе возвращаемыми значениями. Это вроде как аналогично тому, что функция что-то делает для вас, записывает ответ на листке бумаги, а затем передаёт вам, программисту, этот листок бумаги, чтобы вы могли сделать с ним всё, что захотите, не просто транслируя его всему миру с помощью, например, окна диалога на экране. Таким образом, возвращаемое значение имеет отношение к такой программе, потому что помните, когда мы использовали блок Ask, я ввёл своё имя. Где моё имя оказалось изначально? Оно ещё не появилось на экране. Где оно оказалось? В элементе пазла "Ответ". Это особый овальный элемент, как я утверждал ранее, он представляет возвращаемое значение, то есть метафорический лист бумаги, на котором записан ответ, чтобы я мог использовать его позже. Именно к этому мы сейчас и хотим прийти в C - к возвращаемому значению, с которым я могу делать всё, что захочу, выводить его на экран.
Программирование на C требует больше внимания к деталям, но это помогает лучше понять, как работает память компьютера.
Записывает ответ на листке бумаги, а затем передаёт вам, программисту, этот листок бумаги, чтобы вы могли сделать с ним всё, что захотите. Не просто транслируем его всему миру с помощью, например, окна диалога на экране. Таким образом, возвращаемое значение имеет отношение к такой программе. Помните, когда мы использовали блок Ask, я ввёл своё имя. Где моё имя оказалось изначально? Оно ещё не появилось на экране. Где оно оказалось? В элементе пазла Ответ. Это особый овальный элемент, который представляет возвращаемое значение, то есть метафорический лист бумаги, на котором записан ответ, чтобы я мог использовать его позже. Именно к этому мы сейчас и хотим прийти в C: к возвращаемому значению, с которым я могу делать всё, что захочу, выводить его на экран, изменять каким-то образом, сохранять данные или что-то ещё.
Итак, например, вот что мы сделали в Scratch: входными данными для блока "сказать" или блока "спросить" было "Как тебя зовут?" в кавычках. Функция, конечно же, это функция "спросить", а возвращаемое значение было ответ. Если мы сейчас рассмотрим, как мы можем перевести это на язык C, то поначалу это будет выглядеть немного странно, но это будет следовать определённому паттерну. Сегодня, на следующей неделе, через неделю, всякий раз, когда мы будем писать подобный код. Итак, я утверждаю, что функция Get string будет наиболее аналогичной функцией блока "спросить". Чтобы прояснить это, специфическая для CS50 вещь, своего рода учебные колёса. Но через несколько недель мы покажем вам, что делает эта функция и как вы не сможете использовать её в дальнейшем, когда освоите сам язык.
Обратите внимание, что я поставил круглые скобки слева и справа в качестве своеобразного заполнителя для пользовательского ввода, и этим пользовательским вводом будет "Как тебя зовут?". Но я не могу просто поместить "Как тебя зовут?" в скобки. Что мне нужно минимально добавить туда ещё? Да, двойные кавычки слева и справа. Давайте добавим их. Я оставил здесь пробел не для новой строки. Я мог бы переместить курсор на следующую строку, но минимально я хочу переместить курсор хотя бы на один пробел, чтобы это выглядело красиво, чтобы когда меня спрашивали моё имя, между вопросом и моим ответом был пробел. Но это также может быть обратная косая черта N. Это просто мой эстетический выбор.
Но что мне делать с ответом, который возвращается от Get string? Здесь текст будет выглядеть по-другому. В C вы начинаете использовать знак равенства слева направо. Соответственно, слева вы указываете имя переменной, в которой вы хотите сохранить это возвращаемое значение. Возвращаемое значение - это своего рода концептуальная вещь. Вы можете сделать с ним всё, что захотите. Если я хочу сохранить его на более длительный срок в переменной, например, X, Y или Z, как на уроках математики, я могу просто дать ей здесь имя X, Y или Z или что-то более разумное, например ответ или любое другое английское слово без пробелов, обычно в нижнем регистре. Те же эвристики, что и раньше. Но это означает, что теперь вы спросите пользователя, как его зовут, чтобы он не ввёл, сохраните это справа налево в этой переменной под названием ответ.
Но C ещё не закончил с нами. Если вы изучали Python или некоторые другие языки, вы бы уже закончили писать код на этом этапе. Однако в C вы дополнительно должны сообщить компилятору, какой тип переменной вы хотите использовать. Так что если это текстовая строка, вы пишете string, если это целое число, вы говорите int, как мы могли уже видеть раньше. Так что это немного более педантично, честно говоря, это больше раздражает, больше обязанностей на вас, на мне, на программистах в целом. Но это просто помогает компилятору знать, как хранить это в памяти компьютера. И я уже почти закончил с этой строкой кода, но чего не хватает? Итак, точка с запятой. И запомните мои слова: если вы никогда раньше не программировали, на этой неделе, в этом семестре вы забудете точку с запятой точно. У вас опустятся руки, вы будете расстроены, потому что не сможете понять, почему ваш код не работает. Вы столкнётесь с тем, что у вас не получается или что вы не программист. Просто требуется время, чтобы уяснить эти вещи, особенно если язык для вас новый. Итак, вот моя точка с запятой.
Хорошо, давайте тогда сделаем что-нибудь с этим возвращаемым значением, используя второй из больших элементов пазлов в Scratch. Итак, когда я хотел сказать "Привет, Дэвид" или как там зовут человека, я бы складывал свои элементы пазлы вот так. Это на самом деле похоже на Python и, возможно, некоторые другие языки, которые некоторые из вас изучали. Но C немного отличается, и ближайший аналог этого решения в C будет выглядеть так: я всё ещё использую printf, потому что printf - это эквивалент "сказать". Внутри моих скобок я буду, как ни странно, писать "Hello, %s". Так что в C нет реального аналога соединить, вместо этого...
В программировании важны детали: даже запятая может изменить смысл кода.
Почему ваш код не работает? Вы столкнулись с проблемой, и у вас не получается её решить. Возможно, вы не программист, и просто требуется время, чтобы уяснить эти вещи, особенно если язык для вас новый.
Итак, вот моя точка запятой. Давайте тогда сделаем что-нибудь с этим возвращаемым значением, используя второй из больших элементов пазлов. Когда я хотел сказать "привет, Дэвид" или как там зовут человека, я бы складывал свои элементы пазла вот так. Это на самом деле похоже на Python и, возможно, некоторые другие языки, которые некоторые из вас изучали, но C немного отличается. Ближайший аналог этого решения в C будет выглядеть так: я всё ещё использую Print F, потому что Print F - это эквивалент сказать внутри моих скобок. Я буду, как ни странно, писать "Hello %S". В C нет реального аналога для соединения строк, вместо этого есть способ специально форматировать текст с помощью Print F. Отсюда и буква F в Print F. То, что вы делаете в Print F, - это печатаете любое английское слово или человеческие слова, как хотите. Затем вы используете %S в качестве заполнителя. Если вы хотите добавить к своему тексту текстовую строку, вы будете писать буквально %S.
Позвольте мне предвосхитить вопрос из зала: как напечатать %S? Для этого тоже есть решение, если вы когда-нибудь захотите буквально напечатать %S. Но это немного странный выбор символов, так что вероятность того, что нам когда-нибудь понадобится набирать это самостоятельно, настолько мала, что никто об этом особо не беспокоится. Хорошо, но этого не совсем достаточно. В дополнение к "Hello", запятая, пробел и заполнитель %S. И просто для ясности, это код формата. Опять же, формат - это буква F в Print F. Мне всё ещё нужны двойные кавычки вокруг всего этого, чтобы соответствовать моей предыдущей программе. Я собираюсь добавить обратную косую черту \N, чтобы переместить курсор на следующую строку. Сейчас я оставил здесь безумное количество места, но это сделано намеренно.
Есть ли у кого-нибудь предположение, что я вероятно захочу добавить после кавычек, но всё ещё внутри скобок? Ответ: мне нужно каким-то образом сообщить Print F со вторым входным параметром, иначе известным как аргумент, что я хочу подставить вместо %S. Поэтому я ставлю запятую, а затем имя переменной, которую я хочу, чтобы Print F выяснил, как подставить сюда. Честно говоря, это немного раздражает и это своего рода устаревший подход. Более новые современные языки, такие как Python и JavaScript, на самом деле имеют гораздо более удобные для пользователя способы это сделать. Но так вы поймёте эвристику, то есть правило, что это просто форматирование строки путём подстановки того, что вы хотите, в эту так называемую строку формата. И опять же, запятая здесь важна: она означает, что функция принимает один входной параметр слева и второй входной параметр справа. Но обратите внимание на эту запятую: технически здесь две запятые, но я не утверждаю, что эта функция принимает три входных параметра. Почему эта запятая, на которую я указываю, не означает то же самое? Это потому что эта запятая является частью кавычек и частью строки. Совершенно верно, эта запятая, на которую я указываю, является частью кавычек и, следовательно, частью моей строки английского текста. Так что это просто английская грамматика, а это уже своего рода синтаксис C. И опять же, это те самые раздражающие мелкие детали, например, когда мы используем один и тот же символ для разных вещей, но контекст имеет значение. Поэтому просто внимательно смотрите на свой код, тщательно просматривайте его слева направо, и как правило, ответ будет очевиден.
Хорошо, если есть вопросы по этому синтаксису, прежде чем мы действительно напишем и запустим его. Да, почему обратная косая черта \N стоит не после ответа функции? Включая Print F, работают так, что вы передаёте им один аргумент внутри скобок. А если у вас есть второй аргумент, вы ставите его после этой запятой. Но Print F работает так, что его первым аргументом всегда является строка, которую вы хотите отформатировать. Всё, что вы хотите вывести на экран, должно быть заключено в эти кавычки. Вы, возможно, можете сделать вывод из этого: если бы я на самом деле хотел сказать несколько вещей в этом предложении, например, "Hello", может быть, имя и фамилия, я мог бы сделать "Hello, %S %S". Если бы у меня было две переменные, одна с именем, другая с фамилией, мне понадобилась бы ещё одна запятая для третьего входного параметра. Так что в этом смысле F очень универсален.
Вопросы? Да, хорошо. Можно ли абстрагировать саму строку формата "Hello"? Ответ короткий: да, но это сделать не так просто, как в других языках, поэтому мы пока что держим всё простым. Вам очень понравится что-то вроде Python или JavaScript, где большая часть этих сложностей уходит.
Понимание основ программирования сейчас облегчит изучение других языков в будущем.
Всё, что вы хотите вывести на экран, должно быть заключено в кавычки. Вы, возможно, можете сделать вывод из этого, если бы я на самом деле хотел сказать несколько вещей в одном предложении. Например, Hello может быть имя и фамилия. Я мог бы сделать Hello, %s %s, если бы у меня было две переменные: одна с именем, другая с фамилией. Но тогда мне понадобилась бы ещё одна запятая для третьего входного параметра. В этом смысле F очень универсален.
Вопросы? Да, хорошо. Можно ли абстрагировать саму строку формата Hello? Короткий ответ — да, но это сделать не так просто, как в других языках, поэтому мы пока что держим всё простым. Вам очень понравится что-то вроде Python или JavaScript, где большая часть этих сложностей уходит. Но вы также увидите, что в Python, JavaScript и других языках они по-прежнему вдохновляются подобным синтаксисом. Понимание этого сейчас будет полезно для нескольких языков в дальнейшем.
Давайте уже сделаем что-нибудь с этим кодом, а не просто будем говорить о том, что он может сделать для нас. Давайте перейдём обратно в V Code. Я собираюсь удалить эту среднюю строку Print F. Я всё ещё нахожусь в том же файле Hello C. Я собираюсь очистить окно терминала, чтобы устранить отвлекающие факторы. Для этого я могу буквально набрать Clear, но это только ради эстетики, функционально это не так уж полезно. Или вы можете нажать Ctrl L на клавиатуре, чтобы достичь того же эффекта. Но я вернусь к строке пять, где ранее я просто писал Hello world, и вместо этого я сделаю следующее: я создам переменную с именем Answer. Тип будет string. Я присвою ей значение, равное возвращаемому значению функции Get string, задав вопрос на английском языке с одним пробелом. Затем я напишу Print F с открывающей и закрывающей кавычками, Hello заполнитель, обратная косая черта N, запятая, и здесь снова идёт Answer. Мне нужна точка с запятой справа от этого. Теперь я думаю, что закончил.
Позвольте мне указать на пару деталей. Это стало очень красочным и красивым очень быстро. Это не похоже на чёрно-белый код, который я показывал на экране мгновение назад. Это потому что такие программы, как vscode, делают для нас красивую печать или, скорее, подсветку синтаксиса нашего кода. Подсветка синтаксиса означает просто добавление некоторых цветов коду, чтобы различные идеи выделялись. Например, вы заметите, что Print F и Get string выделены фиолетовым цветом, потому что они представляют функции. Точно так же, как блок What your name в кавычках выделен светло-голубым цветом вместо белого. Но это по-прежнему будет последовательным, если я буду использовать строки текста и в других местах. Я не вводил ничего особенного, это не похоже на Microsoft Word или Google Docs, где я выделяю и меняю цвета вещей. Всё это происходит автоматически. Это просто текст в кодировке Unicode, который автоматически интерпретируется и к нему применяются эти цвета, чтобы визуально выделить наиболее полезные вещи.
К сожалению, я допустил ошибку, но сделал это намеренно, потому что вы тоже вероятно допустите эту ошибку. Я снова запущу Make Hello, потому что я изменил свой код, так что мне нужно заново сгенерировать машинный код из нового исходного кода. Но, к сожалению, когда я нажимаю Enter, ошибки даже не помещаются на экране. Позвольте мне сделать это окно больше. Я нажму на маленький символ каретки здесь, чтобы на мгновение увеличить терминал, и вы видите, что строк с ошибками больше, чем строк кода, который я написал, и что они написаны довольно загадочно. Программисты, которые пишут код уже 10-20 лет, могут заметить некоторые детали. Обратите внимание, что проблема определённо с Hello. Это моя вина. Этот синтаксис здесь означает, что проблема в строке п, а следующая п означает символ п. Вы можете буквально вычислить ваш баг, перейдя к строке п, а затем на пять символов вправо. В частности, использование необъявленной сложности. Но важны здесь не детали этой ошибки, а скорее то, что он не распознаёт слова string или Get string. Почему так может быть?
Да, совершенно верно. Поскольку мы используем Get string, который, как я утверждал, является специфичным для cs50 и будет использоваться нами несколько недель, C не знает о нём из коробки, так сказать. Я должен научить компилятор, что Get существует, так же как я научил его, что printf существует, включив соответствующий титульный файл. В этом случае это просто CS. Это теперь сообщает компилятору, что кто-то уже написал эту функцию Get STR, и вместе с ней это тип переменной, называемый STR.
Чтобы компилятор распознал функцию, включите соответствующий заголовочный файл.
Перейдя к строке "п", а затем на пять символов вправо, и где-то в этой области, в частности, использование необъявленной сложности. Но важны здесь не детали этой ошибки, а скорее то, что он не распознаёт слова string или Get string. Почему так может быть?
Да, совершенно верно, поскольку мы используем Get string, который, как я утверждал, является специфичным для CS50 и будет использоваться нами несколько недель. C не знает о нём "из коробки", так сказать. Я должен научить компилятор, что Get существует, так же как я научил его, включив соответствующий титульный файл. В этом случае это просто CS. Это теперь сообщает компилятору, что кто-то уже написал эту функцию Get STR, и вместе с ней это тип переменной, называемый STR. Так что теперь, если я вернусь в окно терминала и снова запущу ту же самую команду Hell, возможно, теперь на самом деле ничего не пойдёт не так, потому что компилятор будет доведен до уровня всей необходимой функциональности. И теперь, если я сделаю это, вот оно: "Как меня зовут?" Обратите внимание, что курсор находится на один пробел дальше, просто потому что я подумал, что это будет выглядеть красивее, чем если бы курсор был прямо рядом с вопросительным знаком. Ввожу "David" в качестве моего ввода и нажимаю Enter, и получаю Hello David. Есть вопросы по любым моментам из этого кода? Вопросы по любому коду?
Нет? Хорошо, давайте добавим некоторые другие функции. Оказывается, что в мире существуют и другие типы данных, не только строки, но и как мы уже говорили ранее, целые числа (сокращённо int) и числа с плавающей точкой (сокращённо float), и некоторые другие. Так что давайте не будем сосредотачиваться только на строках и сделаем что-то более интересное с числами здесь, и посмотрим, что мы можем сделать с чем-то вроде целых чисел. Опять же, взглянув на Get int. И для этого я дам вам несколько других инструментов в нашем наборе инструментов.
Те коды формата, на которые я ссылался ранее, такие как %s, к счастью, довольно простые, и вот список большинства популярных кодов формата, которые вам когда-либо понадобятся. printf в частности, мы видели %s для строк, и вы, возможно, можете догадаться, какой из них мы собираемся использовать для целых чисел. Да, мы будем использовать %i для целых чисел, и это то, что вы можете найти в руководствах или на слайде подобном этому. Но лишь некоторые из них вы будете использовать часто. Давайте используем целые числа в более интересном контексте, не просто с помощью функций. Давайте перейдём к идее условных операторов.
Условные операторы в C были похожи на эти пресловутые развилки на дороге. Типа вы хотите сделать это или это, или то. Это способ принятия решения в программе, который будет супер полезен и практически везде в C, в любых проблемах, которые мы пытаемся решить. Так что позвольте мне дать вам ещё несколько строительных блоков в C, ещё раз сравнив их один к одному.
Итак, вот как бы могли сказать в C: если одна из двух переменных X или Y меньше другой, то скажем в кавычках X меньше Y. Глупая программа, но просто чтобы показать вам базовый синтаксис для C. Вот как бы мы задали вопрос: если X меньше Y, тогда скажите это. Итак, сказать это функция if — это условный оператор, а зелёную штуку здесь мы называли булевым выражением, что просто означает вопрос, ответом на который является истина или ложь, да или нет, один или ноль. Как бы вы не хотели думать об этом, код будет выглядеть так: потребуется немного привычки, немного мышечной памяти, чтобы освоить это. Но вы скажете if, затем в скобках вы скажете X меньше Y, предполагая, что X и Y — это переменные. Затем вы будете использовать эти фигурные скобки. Если вы хотите сказать в кавычках X меньше Y на C, какую функцию вы должны здесь использовать?
Предположительно printf в кавычках X меньше Y. Это немного многословно, но опять же, обратите внимание на шаблон: имя функции printf, в скобках слева направо находится аргумент для printf, который заключён в кавычки X меньше Y. И опять же, просто для эстетики, чтобы переместить курсор на следующую строку, о чём вам не нужно было беспокоиться в Scratch, потому что там всё в диалоговых окнах. Мы также добавляем обратную косую черту \n. Обратите внимание, что эти фигурные скобки, как они называются, очень похожи на оранжевый элемент пазла здесь, они как бы обнимают код. И отмечу, что строго говоря, в C, если у вас только одна строка внутри условного оператора, вы можете полностью опустить фигурные скобки, и код всё равно будет работать, если у вас только одна строка. Почему? Просто чтобы экономить людям несколько нажатий клавиш. Если у вас две строки, три строки или больше внутри, вам нужны фигурные скобки.
Используйте фигурные скобки даже для одной строки в условных операторах, чтобы код был понятнее и напоминал визуальные блоки Scratch.
Обратите внимание на шаблон имени функции Print F. В скобках слева и справа находится аргумент для Print F, который заключён в кавычки: "X меньше Y". Для эстетики, чтобы переместить курсор на следующую строку, мы добавляем обратную косую черту \n. В Scratch вам не нужно было беспокоиться об этом, так как там всё в диалоговых окнах.
Фигурные скобки, как они называются, очень похожи на оранжевый элемент пазла. Они как бы обнимают код. В C, если у вас только одна строка внутри условного оператора, вы можете полностью опустить фигурные скобки, и код всё равно будет работать. Это делается для экономии нажатий клавиш. Однако, если у вас две строки, три строки или больше внутри, вам нужны фигурные скобки. На этом курсе я всегда буду использовать фигурные скобки, чтобы это как можно больше напоминало Scratch. Некоторые из вас, кто программировал раньше, могут поморщиться, но это тоже вопрос стиля, и мы поговорим об этом на курсе. С эстетической и стилистической точки зрения мы можем принимать определённые решения, но как правило, в классе или в компании, вы как студент или сотрудник должны стандартизировать эти правила для форматирования кода.
Теперь рассмотрим двухстороннюю развилку на дороге в Scratch. Если X меньше Y, сказать "X меньше Y", иначе сказать "X не меньше Y". Это будет выглядеть практически так же, но добавляется ключевое слово else с ещё одним набором фигурных скобок и ещё пара Print F. В C это просто текст, без элементов пазлов, но логика остаётся той же.
Что насчёт трёхсторонней развилки на дороге? Если X меньше Y, то сказать "X меньше Y". Иначе, если X больше Y, сказать "X больше Y". Иначе, если X равно Y, то сказать "X равно Y". Это выглядит почти так же, но есть одна странность: двойной знак равенства ==. Это не ошибка или опечатка. Двойной знак равенства используется для сравнения, чтобы избежать путаницы с присвоением переменной, которое обозначается одним знаком равенства =.
В C, когда мы использовали функцию Get string, знак равенства использовался для присвоения значения переменной справа налево. Авторы C решили использовать два знака равенства для сравнения значений. В других языках, например, в JavaScript, есть даже три знака равенства подряд для решения ещё одной проблемы. Разумные люди могут не соглашаться с тем, насколько хороши или плохи эти решения, но это стандарт.
Код по-прежнему правильный, но есть плохое проектное решение. Нужно ли нам задавать третий вопрос else if (X == Y)? Логически, нет. Либо X меньше Y, либо X больше Y, либо они равны. Таким образом, можно избавиться от else if и просто использовать else, избегая двойного знака равенства и экономя время и ресурсы компьютера.
Оптимизируйте свой код, чтобы не тратить время компьютера и свои ресурсы впустую.
В мире арифметики, существует три возможных отношения между двумя числами X и Y: либо X < Y, либо X = Y, либо X > Y. Таким образом, логически, если вы уже знаете, что X не меньше Y и не больше Y, то они должны быть равны. Технически, задавая этот вопрос, вы просто тратите время компьютера и его ресурсы впустую, потому что он уже знает ответ на этом этапе. Это также означает, что вы тратите своё время как программист, набирая лишний код или элементы пазлов, чем вам нужно, потому что логически одно вытекает из другого. Таким образом, можно избавиться от "else if" и просто использовать "else", избегая двойного знака равенства. Это не потому, что двойное равенство неправильно, а потому что вы тратите время впустую, задавая лишние вопросы.
Если у вас есть эти элементы пазла в вашем распоряжении, как мы можем на самом деле использовать их? Предположим, что мы действительно хотим что-то сделать со значениями. Давайте также введём переменные. В C мы видели пример использования строки мгновение назад, но как насчёт целых чисел? Возможно, вы не использовали это в Scratch, но вот оранжевый элемент пазла в Scratch, с помощью которого вы можете создать переменную под названием Counter для подсчёта вещей и установить её равной некоторому значению, например, нулю. Теперь, если я хочу объявить переменную с именем Counter и установить её значение, я использую один знак равенства, потому что логически вы читаете справа налево, или технически это выполняется справа налево. Но этого недостаточно, нам нужен тип данных. Если это будет целое число, то я буду использовать "int". Ещё одна ошибка, которую я продолжаю делать, это забывать точку с запятой в конце строки. Это немного более многословно, чем в некоторых языках, но если вы читаете слева направо, то как вы говорите в C: "дать вам переменную с именем Counter типа int и инициализировать её значением ноль".
Теперь, как насчёт того, чтобы в Scratch изменить эту переменную на единицу, добавив к ней единицу? В Scratch это очень просто: вы просто меняете её на единицу или даже на минус единицу, если хотите идти вверх или вниз. В C оказывается, что у вас есть несколько разных способов провернуть такое. Это потому что равенство - это присвоение. Эта строка кода не говорит, что Counter равен Counter плюс 1, потому что это просто невозможно, используя типичные числа. Но это означает: возьмите значение Counter, добавьте к нему единицу и присвойте обратно переменной Counter. Это как увеличение Counter таким образом. Но это настолько распространённая вещь в C и в программировании - увеличивать или уменьшать значение переменных, что есть более краткий синтаксис. Это идентично, и вам может потребоваться немного практики, чтобы привыкнуть к этому, но это просто экономит вам несколько нажатий клавиш. Это также добавляет единицу или любое другое число, которое вы там используете. Это настолько распространённая операция, особенно в C, что есть ещё более краткий способ выполнить ту же идею: вы можете буквально просто написать "Counter++" и затем точку с запятой. В этом случае все три варианта абсолютно одинаковы и правильны, но со временем вы поймёте, что набор меньшего количества текста на экране вероятно сэкономит вам какое-то время.
Если мы хотели сделать обратное и сделать что-то вроде -1 в Scratch, мы могли бы аналогично сделать "минус минус" в C. В C мы могли бы сделать "минус минус" справа. Это просто некоторые дополнительные строительные блоки перевода из Scratch. Почему бы нам не попробовать использовать это следующим образом? Позвольте мне вернуться к VS Code и предложить сделать что-то вроде этого. Я собираюсь очистить окно терминала, закрыть "h.c.", потому что цель этой программы будет заключаться в сравнении целых чисел. На этот раз я не собираюсь допускать ошибку, я заранее включу "CS", заранее включу "Studio". Очень распространённая ошибка при изучении C - это не "studio.hd", это "studio.h". Теперь внутри Main, что просто является основной частью моей программы, вы можете думать об этом как об аналоге при нажатии зелёного флага - это просто всё запускает. Я собираюсь сделать две вещи: получить целое число под названием X и попросить пользователя ввести это целое число, просто сказав что-то вроде "Что такое X?". Затем я собираюсь сделать "int Y" равным "Get in".
Программирование — это как создание блок-схемы, где каждое условие ведет к новому результату.
Я собираюсь очистить окно терминала и закрыть h.c., потому что цель этой программы будет заключаться в сравнении целых чисел на экране. На этот раз я не собираюсь допускать ошибку и заранее включу CS и Studio. Здесь тоже очень распространённая ошибка при изучении C: это не studio.hd. Теперь внутри Main, что является основной частью моей программы, вы можете думать об этом как об аналоге при нажатии зелёного флага, это просто всё запускает.
Я собираюсь сделать две вещи: получить целое число под названием X и попросить пользователя ввести это целое число, просто сказав что-то вроде "Что такое X" пробел. Затем я собираюсь сделать int Y равным Get in в кавычках "Что такое Y" пробел. Давайте просто сделаем что-то простое: например, если X меньше Y, то выведи в кавычках "X меньше Y" обратная косая черта N точка запятой. Это не очень глубокая программа, она просто будет делать то, что большинство человеческих мозгов могут сделать довольно быстро, но по крайней мере это демонстрирует, как мы можем теперь использовать что-то вроде условного оператора в коде.
Позвольте мне скомпилировать этот код в первый раз: Make compare Enter. Ничего плохого не происходит, что хорошо. Вот как я запускаю программу, и чтобы разобраться с этим, точка означает, что файл находится в вашей текущей папке. Точка означает вашу текущую папку, и мы в конце концов увидим, что две точки означают родительскую папку, например ту, которая содержит то место, где я нахожусь на жёстком диске моего компьютера.
Хорошо, comp. Что такое X? Ввожу 1. Что такое Y? Ввожу 2. Надеюсь, должно быть написано, что X меньше Y. Всё довольно просто, доказательство на примере, и надеюсь, это будет работать и в других случаях. Но если я переверну это и снова запущу compare, введу 2 и 1, ничего не произойдёт. Вы бы ожидали этого, потому что есть только одно булевое выражение, которое решает, следует ли мне вообще печатать это.
Что же происходит? Если это поможет вам, вы можете представлять логику работы любой программы, будь то на Scratch или C, как своего рода блок-схему. Мы будем выкладывать некоторые из них время от времени, особенно если вы мыслите визуально. Это представляет то, что я только что сделал. На этой картинке концептуально показано, где начинается программа. Всякий раз, когда вы видите ромб, вы думаете о булевом выражении, вопросе, который задаётся. Вопрос "X меньше Y" имеет два возможных ответа: истина или ложь, да или нет соответственно.
Позвольте мне предложить, согласно стрелке, что если ответ истина, то выведите согласно этому прямоугольнику "X меньше Y" просто в кавычках, а затем программа завершится. Но логически, если X не меньше Y, то есть ответ на этот вопрос ложный, мы просто перейдём к концу и остановимся. Это диаграмма потока управления, наглядный способ, который вы можете написать на листке бумаги, представляющий то, что делает программа.
Это станет ещё немного более интересным, если теперь мы сделаем с кодом что-то ещё. Например, вместо того чтобы просто делать вывод, что это или то меньше единицы, давайте вернёмся к коду здесь. Позвольте мне очистить окно терминала и добавить else. Итак, else выведите "X не меньше Y". Это не совсем правильно, что было бы разумно здесь сказать, да, тонкость, но "X не меньше Y", потому что они могут быть равны. Мы не знаем, если мы проверяем только два сценария.
Теперь, если я введу, я всё ещё получу тот же ответ. Если я снова запущу точку compare, введу 2 за 1, я теперь получаю противоположный ответ. Это не так хорошо, как нам хотелось бы. Было бы неплохо знать, равно оно или больше, но по крайней мере это весь код, который у нас здесь есть. Просто чтобы показать целостную картину, если я вернусь к моей диаграмме потока управления, вот как это выглядело раньше логически. Теперь, когда я добавил вторую ветвь, если ответ ложный, я сначала вывожу, что "X не меньше Y", а затем останавливаю программу. Та же идея, но дерево решения становится немного больше.
Теперь, что если мы сделаем что-то большее? Давайте добавим третье условие. Позвольте мне вернуться к коду здесь. Я собираюсь открыть окно терминала, чтобы освободить место для большего количества кода, и скажу else if X больше Y, тогда продолжайте и скажите не "X не меньше Y", а скорее "X больше Y". Затем здесь внизу я сделаю else if X равно Y, тогда я могу продолжить искать.
Оптимизация кода — это не только о правильности, но и об эффективности.
Если я вернусь к моей диаграмме и блок-схеме, вот как это выглядело раньше логически. Теперь, когда я добавил вторую ветвь, если ответ ложный, я сначала вывожу, что X не меньше Y, а затем останавливаю программу. Та же идея, но дерево решений становится немного больше. Теперь, концептуально, что если мы сделаем что-то большее? Давайте добавим третье условие. Я собираюсь открыть окно терминала, чтобы освободить место для большего количества кода, и скажу: else if X > Y, тогда продолжайте и скажите, что X больше Y. Затем, внизу, я сделаю else if X == Y, и продолжу с printf("X = Y\n").
Теперь, если я запущу это, открою окно терминала, снова запущу make compare, и затем compare 1 и 2, они одинаковы. Перезапущу снова, и они снова одинаковы. В третий раз, 1 и 1 теперь действительно равны. Это работает правильно. Но почему я сделал акцент на использовании этих elseif? Разве я не мог бы просто немного упростить свою жизнь и сказать: если это, то это, если это, то это, и так далее? Просто задайте все три вопроса, держите код простым, не беспокойтесь об этих elseif. Будет ли это работать? Да, это экономит немного времени, потому что в этом случае, как и в английском языке, это как отдельные вопросы, и это не использует никакую информацию из предыдущих вопросов, чтобы решить, стоит ли задавать следующий вопрос.
Другими словами, если X меньше Y, и вы уже выяснили это, потому что это единица и двойка соответственно, вы собираетесь напечатать это. Зачем тратить время на этот вопрос, если он не будет истинным? Смысл, который я хотел донести, заключается в том, что если мы визуализируем конкретный дизайн блок-схемы, то зададим вопрос X < Y, затем X > Y, и, наконец, X == Y. Независимо от значений X и Y, вы задаете все три вопроса каждый раз. Но если мы сделаем то, что сделали в первый раз, и вернемся к коду, отменим изменения и добавим обратно, блок-схема будет выглядеть немного сложнее, но она будет лучше спроектирована и более эффективна.
Почему? Потому что я начну сверху, задам вопрос X < Y, если ответ истинный, я говорю X < Y и останавливаюсь, задав только один вопрос. Но если X не меньше Y, я задам второй вопрос, и если ответ истинный, я выведу X > Y и остановлюсь. Только в редком случае, когда X действительно равно Y, я задам третий вопрос, чтобы выяснить, нужно ли печатать что-нибудь вообще. Таким образом, код остается правильным, но эта версия лучше, потому что чаще вы будете идти по одной из первых двух ветвей, а не по самой длинной.
Есть ли вопросы по этому коду или его визуализации? Почему я вообще потрудился задать этот вопрос? Потому что, когда я нажму эту кнопку, надеюсь, у меня есть нужный код. Это будет лучше, чем предыдущий дизайн. Обратите внимание, что если X < Y, мы говорим об этом и останавливаемся. Если X не меньше Y, но больше Y, мы останавливаемся. Или, если оно не больше, мы сразу делаем вывод, что X действительно равно Y, и снова останавливаемся. Эта картинка настолько эффективна и хорошо продумана, насколько мы можем улучшить эту логику. Это почти самое лучшее решение этой проблемы, которое мы можем придумать.
Если я вернусь к своему коду, чтобы он соответствовал этому, единственное, что мне нужно сделать, это перестать тратить время компьютера впустую. Не задавайте третий вопрос, просто логически и математически делайте вывод, что оно будет равно на этом этапе. Есть ли другие вопросы по этому поводу? Извините, немного громче. Очень хороший вопрос: что если я введу что-то, что не является числом? Здесь библиотека CS50 и реализация GetInt будут вашими друзьями.
Оптимизируйте код, чтобы избежать ненужных проверок и повысить безопасность.
Если значение больше Y, мы останавливаемся. Если оно не больше, мы сразу делаем вывод, что X действительно равно Y, и снова останавливаемся. Эта картинка настолько эффективна и хорошо продумана, насколько мы можем использовать эту логику. Это почти самое лучшее решение этой проблемы, которое мы можем придумать. Итак, если я вернусь к своему коду, чтобы мой код на C соответствовал этому, единственное, что мне нужно сделать, - это перестать тратить время компьютера впустую. Не задавайте этот третий вопрос, просто логически и математически делайте вывод, что, конечно, оно будет равно на этом этапе.
Хорошо, есть ли другие вопросы по этому поводу? Извините, немного громче. Очень хороший вопрос: что если я введу что-то, что не является числом? Здесь библиотека CS50 и реализация Get in будут вашими друзьями. Например, если я запущу и захочу сравнить кошек и собак, я могу ввести "Cats" и нажать Enter. Он просто будет снова и снова запрашивать у меня ввод. Он также не позволит мне ввести "Dogs", он заставит меня дать ему целое число. C не делает этого по умолчанию. И на самом деле, как мы скоро увидим в течение CS, это на самом деле опасный язык в конечном итоге, потому что он просто доверяет, что человек делает то, что он хочет. Многие современные программы, которые так или иначе взламываются, если они используют C или другой язык под названием C++, на самом деле очень уязвимы для определённых типов взломов. В то время как другие языки, к которым мы перейдём в классе, менее уязвимы по тем же причинам.
Итак, помимо этого, давайте рассмотрим ещё один тип данных, кроме строк и целых чисел. Есть этот другой тип данных в C, известный как char для одного символа. Давайте разберём его. Строка - это действительно строка, это ноль или более символов вместе. Char - это всегда ровно один символ. Не все языки утверждают различие между одним символом и строкой символов, но в C строка обычно состоит из нескольких символов, но теоретически может быть нулевой. По совпадению, она может быть единичной, естественно, она может быть и больше, но char - это буквально, как следует из названия, один символ.
Итак, учитывая это, обратите внимание, что в библиотеке CS50 помимо Get string и Get in, у нас также есть Get char, ещё одна удобная функция для получения одного символа от пользователя. Почему нам может быть полезно получить только один символ от пользователя? Ну, что если вы просто делаете то, что вы делаете довольно часто, когда устанавливаете новое программное обеспечение или заполняете какую-то форму с условиями? Позвольте мне вернуться и создать новую программу под названием agc, что-то вроде запроса согласия пользователя. Итак, я набираю "code agc" и собираюсь быстренько набросать некий шаблон. Включаю cscl, а затем внутри main, что похоже на зелёный флаг нажат, я сделаю следующее: получить символ от пользователя с его простым вопросом, например, "Вы согласны?", ожидая ответа "да" или "нет".
В начале этой строки мне нужно где-то поместить возвращаемое значение, поэтому я помещаю его в переменную с именем "с". В программировании, если вы просто получаете одно значение, иногда нормально использовать X и Y или C. В более крупных программах вы выигрываете от использования реальных слов, таких как Answer, как мы делали с самого начала. Но "с" должен быть определённого типа, поэтому я буквально скажу char, а затем закончу свою мысль точкой с запятой. Вот как я могу проверить, согласен ли пользователь или нет. Я могу сделать что-то вроде этого: если значение равно в кавычках строчной "Y", то продолжай и выведи обратную косую черту. Иначе, если переменная имеет значение равное строчной "N", давайте выведем, скажем, как будто я соглашаюсь или нет с какими-то условиями.
Обратите внимание, что это не опечатки. Что я сделал совсем немного иначе, чем в последний раз, когда использовал текстовые кавычки вместо двойных кавычек. Итак, вот эвристика: при использовании строк, которые обычно состоят из нескольких символов, необходимо использовать двойные кавычки. При использовании одного символа вы должны использовать одинарные кавычки вокруг одного символа. Позвольте мне теперь создать Enter и ввести для "Yes". Кажется, работает. Позвольте мне запустить это снова для "N". Кажется, работает. И просто если я введу что-то случайное, например, знак вопроса, я не знаю, он не падает, он просто игнорирует меня, потому что у меня было только два булевых выражения там.
Но обратите внимание, можно утверждать, что это на самом деле немного ошибочно. Позвольте мне запустить снова то agree Enter. Как насчёт заглавной "Y", потому что, например, у меня нажат capslock? Хорошо, он просто игнорирует меня. Позвольте мне сделать это снова то AG заглавное "N".
Учись программировать с нуля и создавай свои веб-приложения с искусственным интеллектом!
Для строк, которые обычно состоят из нескольких символов, необходимо использовать двойные кавычки. При использовании одного символа вы должны использовать одинарные кавычки. Позвольте мне теперь создать Enter и ввести "Yes". Кажется, работает. Позвольте мне запустить это снова для "N". Кажется, работает. Если я введу случайный символ, например, знак вопроса, он просто игнорирует меня, потому что у меня было только два булевых выражения там.
Обратите внимание, можно утверждать, что это на самом деле немного ошибочно. Позвольте мне запустить снова с "agree". Как насчёт заглавной "Y"? Например, у меня нажат Caps Lock. Хорошо, он просто игнорирует меня. Позвольте мне сделать это снова с заглавной "N". Он снова игнорирует меня, но это должно иметь смысл, потому что я буквально проверяю на строчные буквы.
Как я могу это исправить? Не просто меняя строчные на заглавные, потому что тогда это ломает программу в обратном направлении. Давайте просто добавим здесь ещё одну ветвь. Если переменная равна заглавной букве, я могу здесь сказать, а затем позвольте мне закрыть терминал, чтобы освободить больше места. В противном случае, здесь внизу, для заглавной "N" давайте опять скажем "F". Я утверждаю, что теперь это будет работать. Это четырёхсторонняя развилка на дороге, но я по крайней мере проверяю строчные и заглавные буквы для "Y" и "N" соответственно.
Я утверждаю, что это правильно. Но даже если вы никогда раньше не программировали, это тоже должно начать вас раздражать, потому что мы можем сделать лучше. Это не самый лучший дизайн. Почему так может быть? Мы могли бы просто принудительно сделать переменную "C" заглавной или строчной, независимо от того, что вводит человек. Мы просто делаем это сами, чтобы упростить до двух возможных сценариев. Мне это нравится, но мы ещё не видели функций, которые позволили бы менять символы на заглавные или строчные. Мы дойдём до этого, но хорошая интуиция.
Другие мысли? Мы могли бы использовать логическое "или". Что мне не нравится в этом, так это повторение. В программировании и в жизни в целом есть принцип "не повторяйтесь без необходимости". У меня буквально одна и та же строка на 10 и 14, и одна и та же строка на 18 и 22. В конце концов, я потратил в два раза больше времени, чем нужно. Если я захочу изменить что-то, например, быть более восторженным и написать "согласен", я могу забыть изменить это в другом месте. Это может быть ошибкой, потому что я хочу, чтобы они были согласованы.
Не создавайте ситуации, когда вы можете изменить что-то в одном месте, но не в другом. Просто пишите это только в одном месте. Мне нравится идея объединения вещей с помощью "или". Позвольте мне удалить то, что я только что написал. Пока это на экране, когда вы выделяете код в соответствии с нашей конфигурацией, эти точки просто показывают вам, насколько я сделал отступ. Все стилистические соглашения обычно заключаются в отступе на четыре пробела. Эти точки просто помогают вам считать, не прибегая к мануальному осмотру.
Позвольте мне удалить эти строки. Это будет выглядеть немного странно, но способ, которым вы можете объединить две мысли с помощью "или", это не говорить "или", а использовать две вертикальные черты. Это синтаксически означает английское слово "или". Вы можете просто задать другой вопрос: если "C" равно заглавной букве "Y", а затем здесь я могу сказать "или C равно заглавной букве N". Это добавляет немного больше кода к каждой из этих строк, но не добавляет избыточности, потому что я не дублировал свой "printf" и не добавлял больше фигурных скобок без необходимости.
Кстати, есть противоположность "или" — логическое "и", два амперсанта. Это способ выразить, что вещь слева должна быть истиной и вещь справа должна быть истиной. Но это не имеет смысла в контексте строки, потому что символ не может быть одновременно в нижнем и верхнем регистре. Таким образом, действительно, "или" — это то, что нам нужно в этом случае.
Другие вопросы? Хороший вопрос через CS. Есть ли способ сравнивать строки? Короткий ответ — нет, но предоставит нам такую возможность на следующей неделе. Помимо всего прочего, мы научимся сравнивать строки. Если вы уже программировали раньше, вы увидите, что в C это работает не так, как вы могли бы ожидать, но это тоже проблема, которую мы решим.
Другие вопросы по этой логике? Просто чтобы это стало реальным. Каждый раз, когда вы нажимаете на одно из тех лицензионных соглашений или условий использования в форме программного обеспечения, вероятно, под капотом есть код, такой же простой, как этот. Может быть, он графический, может быть, он проверяет, нажимаете ли вы кнопку или клавишу Enter, но под капотом предположительно есть какое-то условное выражение, проверяющее такие входные данные.
Я убеждён, что обучение в IT должно быть доступно каждому. Именно поэтому я создал уникальный курс для тех, кто хочет освоить программирование с нуля. Что делает этот курс уникальным? Мы предлагаем полный набор базовых знаний: от решения задач и структур данных до алгоритмов и баз данных. Обучение сразу двум популярным языкам — Python и JavaScript. Понимание работы веба и создание собственного веб-приложения с искусственным интеллектом. Практические советы по развитию карьеры и поиску работы, основанные на моём личном опыте в индустрии.
Наш курс представлен на трёх уровнях объяснения. Если что-то непонятно на одном уровне, переходите на следующий, где материал изложен ещё проще. Такой подход вы больше нигде не встретите. И самое главное, курс стоит в десятки раз дешевле аналогичных программ от раскрученных школ и станет отличной инвестицией в ваше будущее. Ссылка на курс с весомой скидкой в описании под видео. Присоединяйтесь и начните свой путь в IT уже сегодня.