
- Цели первой недели
- IDE CS50
- Командная строка и обновление рабочей среды
- Работа в IDE
- Hello, C!
- Баги?
- Проверка на правильность: тест check50
- Основы С: сравнение со Scratch
- Основные типы данных в C
- Библиотеки С
- И снова Hello C: разбор синтаксиса простейших программ
- Еще немного о вводе/выводе в C
- Ввод данных с проверкой: специальные функции библиотеки cs50.h
- Задание 1. Умный подсчет расхода воды
- Задание 2. С нами Марио!
- Задание 3. Время получать сдачу
- Как подтвердить правильность кода и получить оценки
- Ресурс кода
- Дополнительная литература
Ввод данных с проверкой: специальные функции библиотеки cs50.h
Для более удобного прохождения этого курса, мы разработали специальную библиотеку CS50, в которой, в частности, есть очень полезные функции обработки введенных пользователем данных.GetString()
считывает введенную пользователем строку;GetInt()
считывает введенную пользователем строку и проверяет, не записано ли в ней целое число;GetFloat()
считывает введенную пользователем строку и проверяет, не записано ли в ней число с плавающей точкой;GetLongLong()
считывает введенную пользователем строку и проверяет, не записано ли в ней длинное вещественное число.
Задание 1. Умный подсчет расхода воды

water.c
в вашей директории ~/workspace/pset1
. Программа должна подсчитывать сколько бутылочек воды уходит на душ зависимости от времени. То есть:
- Программа запрашивает у пользователя количество минут, проведенных в душе
- Пользователь вводит положительное целое число
- Программа выводит на экран количество бутылочек, израсходованных пользователем.
username:~/workspace/pset1 $ ./water
minutes: 10
bottles: 120
Для простоты в этот раз мы будем считать, что пользователь всегда вводит число минут верно, то есть, мы не проверяем, было ли введено положительное и целое число. Позднее мы научимся писать проверки, но пока достаточно и этого.
Чтобы проверить правильность выполнения программы с помощью check50,
нужно ввести следующую строку в терминале:
check50 2015.fall.pset1.water water.c
А если вы хотите посмотреть, как работает программа water
, написанная сотрудниками курса выполните следующую команду:
~cs50/pset1/water
Задание 2. С нами Марио!

mario.c
в вашей директории ~/workspace/pset1
. Наша рограммка будет рисовать полупирамиду, подобную той, что вы видите, но прямо в консоли, без графики: каждый из блоков будет состоять из значка хэша (#). Даже если вы еще не сообразили, как это сделать, поверьте: это просто. Чтобы сделать задачу более интересной, добавим в неё возможность задавать высоту полупирамидки с помощью неотрицательного целого числа от 0 до 23. Высота пирамидки на картинке считается в самом высоком месте, то есть равна 8. Если пользователь неправильно вводит число, нужно попросить его сделать это ещё раз. Затем сгенерировать (с помощью printf пирамидку).
Озаботьтесь тем, чтобы выровнять нижний левый угол вашей полупирамиды по левому краю окна терминала, как в примере ниже. Подчеркнутый текст — это то, что пользователь вводит самостоятельно.
username:~/workspace/pset1 $ ./mario
height: 8
##
###
####
#####
######
#######
########
#########
Обратите внимание, что два крайних правых столбца имеют одинаковую высоту. Генерировать трубы, облака и самого Марио пока не стоит=). По крайней мере для этого задания.
Если пользователь ввел неправильные данные (ввел не число, или число, которое меньше единицы или больше, чем 23), программа должна снова попросить его ввести данные, как в примере внизу, где подчеркнутый текст — то, что вводил пользователь с клавиатуры.
Для считывания введенной строки используйте GetInt
. Она может помочь проверить неправильный ввод, но не для всех случаев.
username:~/workspace/pset1 $ ./mario
Height: -2
Height: -1
Height: foo
Retry: bar
Retry: 1
##
Чтобы скомпилировать программу, введите строку в терминале:
make mario
или более прозрачный, но длинный вариант:
clang -o mario mario.c -lcs50
после этого запустите программу на исполнение:
./mario
Если вы хотите проверить правильность выполнения программы, запускайте check50
:
check50 2015.fall.pset1.mario mario.c
А если вы хотите поиграться с версией mario, созданной ассистентами курса, mario набирайте следующую строку:
~cs50/pset1/mario
Задание 3. Время получать сдачу

greedy.c
в своей директории ~/workspace/pset1
.
Дано: монетки номиналом 25, 10, 5, 1 цент
Программа должна:
- Спросить пользователя, сколько сдачи нужно выдать
- Посчитать минимальное количество монет, с помощью которых можно это сделать
GetFloat
из библиотеки CS50 и printf
из стандартной библиотеки ввода/вывода для вывода. Кроме того, программа должна проверять корректность ввода.
Мы попросили вас использовать GetFloat
, чтобы пользователь мог вводить значение в долларах и центах через точку. Например, если мы должны $9.75, пользователь должен ввести 9.75, но не $9.75 или 975.
Вы должны проследить, чтобы пользователь ввел число, которое имеет смысл. Скажем, неотрицательное, в этом функция GetFloat
сама по себе не поможет. Если пользователь сделал неправильный ввод, нужно просить его повторить его и выполнять программу только с корректными данными.
Остерегайтесь неточностей, свойственных числам с плавающей точкой. Например, 0.01 не может быть представлено непосредственно как float
. Попробуйте использовать форматированный вывод, например, с 50 знаками после запятой, используя указанный ниже код:
float f = 0.01;
printf("%.50f\n", f);
Кстати, перед тем, как что-либо считать, будет логично перевести всю сумму в центы, (и заодно преобразовать её из float
в int
), что поможет избежать массы ошибок и сложностей.
Чтобы наш автоматический анализатор кода мог правильно проверить вашу задачу, убедитесь, что последняя строка вывода вашей программы не содержит никакой другой информации, кроме минимального количества монеток: целое число с символом \n после него (те, кто учится на JavaRush, прекрасно знают, о чём мы здесь говорим =)).
Ниже — пример, как должен выглядеть результат работы вашей программы.
username:~/workspace/pset1 $ ./greedy
O hai! How much change is owed?
0.41
4
Учитывая особенность чисел с плавающей точкой, можно игнорировать нуль и вводить такое число в форме .41. Конечно, пользователи, которые захотят проверить программу на возможность ввода некорректных данных по полной, должны увидеть что-то вроде:
username:~/workspace/pset1 $ ./greedy
O hai! How much change is owed?
-0.41
How much change is owed?
-0.41
How much change is owed?
foo
Retry: 0.41
4
Исходя из этих требований и примера, который вы увидели выше, ваш код, скорее всего, должен содержать какой-то цикл.
Если во время тестирования приложения вы поймете, что цикл не останавливается, вы можете прервать выполнение программы комбинацией ctrl-c (иногда — многократной).
Как компилировать и выполнять программу вы уже знаете. Если вы хотите проверить правильность работы вашей программы, с помощью утилиты check50
, в терминале введите следующую строку:
check50 2015.fall.pset1.greedy greedy.c
А если вам захочется поиграть с этой программой, выполненной ассистентами курса, пропишите следующую команду:
~cs50/pset1/greedy
Как подтвердить правильность кода и получить оценки
Вариант 1
Если вам важно проверить именно правильность кода, а не получить итоговую оценку, вы можете его проверять и исправлять с помощью команды.
check50 2015.fall.pset1.name name.c
введенной в терминальной строке CS50 IDE? где
name
— название файла вашей задачи.Вариант 2
Если же вы хотите получить оценки (по сути, тот же запуск check50, но с запоминанием результата и заполнением некоторых форм на английском, тогда проделайте следующие шаги:
Шаг 1 из 2
- Когда приложения готовы, залогиньтесь в CS50 IDE.
- В левом верхнем углу CS50 IDE в пределах его файлового браузера, а не терминального окна, кликните левой клавишей мыши с удержанием ctrl или правой клавишей мыши по вашему файлу hello.c (тому, который лежит в директории pset1 ) и нажмите Download. Вы должны обнаружить, что браузер загрузил hello.c.
- Повторите для water.c.
- Повторите для mario.c.
- Повторите для greedy.c.
- В отдельной вкладке или окне залогиньтесь в CS50 Submit.
- Нажмите Submit в левом нижнем углу окна.
- Под Problem Set 1 на появившемся окне нажмите на Upload New Submission.
- На появившемся окне жмите Add files…. Должно появиться окно с именем Open Files.
- Пройдите путь к месту, куда загружен hello.c. Обычно он находится в папке Downloads или в той папке, которая назначена у вас по умолчанию для загрузки. Найдя hello.c, нажмите на него один раз чтобы отметить, затем нажмите Open.
- Кликните Add files… снова, и окно Open Files снова появится.
- Теперь найдите таким же образом файл water.c. Кликните по нему, затем кликните Open (или «Открыть»).
- Теперь находите mario.c. И тоже кликайте и открывайте таким же образом.
- Все то же самое с файлом greedy.c.
- Нажмите Start upload чтобы начать загрузку ваших файлов на серверы CS50.
- На появившемся экране вы увидите окно с надписью No File Selected. Если вы переместите курсор мыши в левую часть окра, вы увидите список файлов, которые вы загрузили. Нажмите на каждый, чтобы подтвердить содержание каждого из них. (Нет необходимости нажимать на другие кнопки или иконки). Если уверены, что готовы отослать файл на проверку, считайте, вы все сделали! Если хотите проверить свой код самостоятельно ещё раз или исправить что-либо, возвращайтесь в CS50 Submit и повторите эти шаги. Вы можете повторно отправить столько раз, сколько вы хотите; оцениваться будет только самое последнее представление.
Шаг 2 из 2 (он не обязателен для оценки, если что=))
Теперь перейдите по ссылке https://www.edx.org/course/cs50s-introduction-computer-science-harvardx-cs50x где вы обнаружите специальные формы. В них нужно ответить на несколько теоретических вопросов, и затем нажать Submit под ними.
- Alright, should've seen this one coming! In just a few sentences, what's a library? * (Кратко опишите, что такое библиотека)
- In just a few sentences, what role does
#include <cs50.h>
play when you write it atop some program? *(какова роль строки #include <cs50.h>, которая фигурирует в верхней части кода некоторых программ?) - About how many hours would you say you spent on Problem Set 0: Scratch?(сколько времени у вас заняли задачки нулевой недели (Scratch)
- About how many hours would you say you spent on Problem Set 1: C?(как долго вы решали задачки первой недели по C?)
- What's your opinion of CS50x thus far? *(Ваше мнение о CS50 в настоящий момент, выбрать вариант нравится-не нравится)
- Have you asked for help from classmates or staff via CS50s Facebook Group at http://www.facebook.com/groups/cs50? *(обращались ли вы за помощью к другим студентам или ассистентам в группе facebook)
- Have you asked for help from classmates or staff via CS50s Subreddit at http://www.reddit.com/r/cs50 *(обращались ли вы за помощью к другим студентам или ассистентам через Subreddit)
- Have you asked for help from classmates or staff via Twitter using @cs50 or #cs50? *(просили ли вы помощи у других студентов или ассистентов в Twitter используя @cs50 или #cs50).
Ресурс кода:
Лекция три
Лекция четыре
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
По условию задачи после введения числа его нужно проверить- оно должно быть от 0 до 23
З.Ы.(я знаю что до этого мы рассматривали от 2 до 23, это не важно)
} while (условие)
по-русски это «сделай, проверь, продолжай делать если условие истинно»
while (условие) {
}
по-русски значит «делай пока условие истинно»
Вы на каком уровне JavaRush? Как выполняли задачи?
Вы мне пытаетесь доказать то что я и так знаю, он должен СНАЧАЛА выполнить условие, потом проверить на правильность, (тут я конечно не много запутался) и в случае ВЫПОЛНЕНИЯ условия повторить, если же условие не выполнилось, закончить цикл.
Суть отсюда не меняется, Сначала условие, потом проверка!
Давайте по шагам ваш код проверим:
Спросили высоту. Записали в h ответ пользователя. Например, 10.
Проверили: 24 > 10 — верно, 10 > 0 — тоже верно. Поэтому повторяем действия. Спросили высоту. Записали в h ответ, например, -5. Проверили: 24 > -5 — верно, -5 > 0 — не верно. Вышли из цикла.
Именно так работает ваша программа сейчас?
1) Цикл типа
Работает следующим образом. Сначала выполняются все операции между фигурными скобками (то есть тело цикла выполняется как минимум один раз), потом проверяется условие и если оно истинно, то повторяем весь цикл.
2) Цикл типа
Работает несколько иначе. В нем условие проверяется перед выполнением цикла. Если оно истинно, то выполняются операции внутри фигурных скобок (тело цикла). Если же при первой же проверке условие не будет соответствовать истине, то данный цикл вообще никогда не будет выполнять свое тело.
1. получить некоторое число от пользователя
2. проверить находится ли оно в заданном диапазоне
3а. если да то продолжить выполнения задачи с этим числом
3б. если нет, то выдать ошибку/запросить новое число и проверить его.
Очень помогает в решении разбивать задачи на отдельные сегменты и делать все в строгом соответствии с поставленной задачей.
Надеюсь, что хоть в чем-то смог помочь))
Правда он полностью на английском. Я прохожу его. Там даже за отдельную плату можно получить сертификат, что прошли Гарвардский курс))
Возвращаюсь к своим баранам. Моя проверка кредиток работает не правильно и я не могу понять где ошибка. Вернее я, по всей видимости, не правильно понимаю как должен работать алгоритм. Например 4111111111111111 должно определятся как VISA. Ок. Как это вижу я (и собственно как реализован мой алгоритм)
1) Берем все вторые числа и умножаем каждое на 2 ( 1*2=2, 1*2=2, 1*2=2, 1*2=2, 1*2=2, 1*2=2, 1*2=2, 1*2=2)
2) Складываем все полученные числа (если число бошьше 10 то его разбираем по разрядно и сначала складываем то чтополучилось (напр. 15 = 1 + 5 + 6)). Для нашего условия (2+2+2+2+2+2+2+2 = 16)
3) Складываем все нечетные элементы первоначального числа (4+1+1+1+1+1+1+1 = 11)
4) Складываем результаты двух сложений (16 + 11 = 27)
5) Если результат делится на 10 без остатка — значит это валидная VISA (в нашем примере)
НО 27 никак не делится на 10 без остатка. То есть одно из двух: либо это не валидная ВИЗА, либо я не правильно понимаю алгоритм.
Подскажите кто поумнее, а?
То есть ввод осуществить в одну переменную типа лонг. И второй подводный камень для меня тут это возможность ввести последовательность чисел в массив, так, чтобы каждое из них стало отдельным его элементом, не используя при этом Enter. То есть что бы ввод выглядел как: 1948718473, а не как:
1
2
3
4
…
н
Как решишь, оставь почту, могу поделиться решением
На edx дедлайн до декабря примерно. Потом будет тот же курс, но в редакции следующего года.
403 You don't have permission to do that!
Есть кто-то на опыте, можете немного прояснить?
Есть здесь в начале: info.javarush.ru/javarush_articles/2016/07/18/%D0%94%D0%BE%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BC%D0%B0%D1%82%D0%B5%D1%80%D0%B8%D0%B0%D0%BB%D1%8B-%D0%BA-%D0%BB%D0%B5%D0%BA%D1%86%D0%B8%D1%8F%D0%BC-CS50-Week-1-%D0%BB%D0%B5%D0%BA%D1%86%D0%B8%D0%B8-3-%D0%B8-4-.html
Сначала тоже делал с помощью 2 циклов, расставления пробелов и т.д., потом:
1. нашел интересную функцию, «не имеюющую аналогов в мире»™ — strncat(s1, s2, i) — это позволило избавиться от 1 цикла.
2. нашел классную фишку в printf — знак *
3. минут 20 промурыжился с ошибкой Segmentation fault. Оказалось, что в C нелья просто так взять и конкатенировать строки, как в джаве, злобный компилятор не даст ни грамма лишней памяти :) Решилось через объявление максимального размера при инициализации переменной — char string[40] = "##";
В общем, что-то мне все это напоминает… задачка на 5 строк, а времени 2 часа :) Где-то я все это уже видел…
Сделал цикл, проверяю с помощью команды «check50 2015.fall.pset1.greedy greedy.c». Все верно, но для числа 4.2 выводится неточный ответ (должен быть 18, а у меня 22). Стал разбираться из-за чего. После того, как я из долларов (4.2) перевожу в центы, должно быть 420 центов, но почему-то именно данное число (я проверял) меняется на 419. Вот кусочек, где я меняю из долларов в центы. x — центы.
P.S. Но благодаря вашему комментарию, заметил, что если вместо float использовать double, то программа работает точно. Но все равно тот момент мне непонятен.
я не знаю, что там по заданию, но старайтесь считать все в центах и пользоваться сдвигом
Мы вводим 1.24, а компилятор видит что-то вроде 1.249999946, и не округлив, мы теряем цент.
я делала так: int toCents (float amount)
{
return round(100*amount);
}
по идее должно помочь. Если что-то неясно, пишите, я уточню.
зы: опыта на с не было вообще
В правильных местах он поможет поменять направление пирамидки.