Лекция 1
Лекция 2
Видео:
1. Массивы
2. Возвращение результата
3. Область видимости
4. Глобальные переменные
5. Перенаправления
6. Шифр Цезаря
7. Шифр Виженера
8. RSA
Путеводитель:
1. Функции - 0
2. Функции - 1
3. Float - 0
4. Float - 1
5. Float - 2
6. String - 0
7. String - 1
8. String - 2
9. ASCII-0
10.ASCII - 2
11. CAPITALIZE-0
12. CAPITALIZE-1
13. CAPITALIZE-2
14. Ages
15. Argv - 0
16. Argv - 1
17. Argv - 2
Конспект семінарського заняття з тижня №2 ви можете переглянути за посиланням http://prometheus.org.ua/cs50/sections/section2.html.
Практическое задание:
1.Инициализация.
У файлі під назвою
Задля автоматизації деяких перевірок вашого коду, програма повинна працювати як у прикладі, наведеному нижче. Підкреслений текст – це ввід користувача, тобто те, що він набрав на клавіатурі.
Згадаємо коротке відео від David DiCiurcio, де розповідається, що шифр Цезаря полягає в тому, щоб циклічно зсунути алфавіт на деякий ключ, який становить кількість літер на які робиться зсув (можете порівняти з http://en.wikipedia.org/wiki/Caesar_cipher). Іншими словами, якщо р - деякий звичайний текст (тобто незашифрований), pi - i-й символ в р, a k -ключ (невід’ємне ціле число), то кожна літера, ci, в шифрованому тексті c, обчислюється таким чином:
ci = (pi + k) % 26
Може здатися, що ця формула робить шифр складнішим, ніж він є насправді, але це лише гарний шлях точного та стислого вираження алгоритму. А вчені таке люблять.
Наприклад, припустимо, що є секретний ключ k = 13 та звичайний текст р: "Be sure to drink your Ovaltine”. Давайте зашифруємо p та k, щоб отримати шифр c зі зміщенням кожної літери тексту p на 13 позицій
отримаємо:
Ми навмисно вивели все шифром, з одноковою шириною літер, щоб все виглядало гарно. Зверніть увагу на те, що літера
Між іншим, шифр Цезаря з ключем 13, як правило, називають
В іншому випадку, програма повинна перейти до запиту тексту, який потрібно зашифрувати; символи, які не є літерами алфавіту, будуть виведені без змін. Після виведення зашифрованого тексту програма повинна завершитися,
Якщо ви явно не повертаєте
У всякому разі, не дивлячись на те, що існує тільки 26 літер в англійському алфавіті, ви не можете припустити, що
Ваша програма має також враховувати, що при введенні великих літер вони повинні залишитися великим, а при введенні малих - малими.
З чого ж почати? Що ж, так як ця програма має стартувати з того, що в командному рядку вона повинна прийняти значення
Нагадаємо, що
Таким чином, ви можете отримати доступ до
якщо припустити, що там щось насправді є! Нагадаємо, що
Те, що користувач вводить ціле число в рядок, ще не означає, що внесене буде автоматично зберігатися в тип
Зверніть увагу, що на цей раз ми оголосили
Оскільки
Отже, як тільки ви отримали
Після того, як у вас є
Іншими словами, так само, як
Між іншим, потрібно підключити ще один файл, щоб використовувати
Лекция 2
Видео:
1. Массивы
2. Возвращение результата
3. Область видимости
4. Глобальные переменные
5. Перенаправления
6. Шифр Цезаря
7. Шифр Виженера
8. RSA
Путеводитель:
1. Функции - 0
2. Функции - 1
3. Float - 0
4. Float - 1
5. Float - 2
6. String - 0
7. String - 1
8. String - 2
9. ASCII-0
10.ASCII - 2
11. CAPITALIZE-0
12. CAPITALIZE-1
13. CAPITALIZE-2
14. Ages
15. Argv - 0
16. Argv - 1
17. Argv - 2
Конспект семінарського заняття з тижня №2 ви можете переглянути за посиланням http://prometheus.org.ua/cs50/sections/section2.html.
Практическое задание:
1.Инициализация.
У файлі під назвою
initials.c
напишіть програму, що запитує у користувача його ім’я (використовуючи GetString
, щоб отримати його у вигляді string
) і потім виводить ініціали у верхньому регістрі без пробілів або крапок із переводом рядку (\n
)
і нічого більше. Вважайте, що ввід користувача складатиметься лише з
літер (верхнього та/або нижнього регістрів) з пробілами. Люди з іменами Joseph Gordon-Levitt
, Conan O’Brien
, та David J. Malan
точно не використовуватимуть вашу програму. Проте, введення користувача
може бути трохи кривим, у разі чого є ймовірність присутності одного
або більше пробілів на початку та/або кінці вводу або навіть
багато-багато пробілів підряд.Задля автоматизації деяких перевірок вашого коду, програма повинна працювати як у прикладі, наведеному нижче. Підкреслений текст – це ввід користувача, тобто те, що він набрав на клавіатурі.
jharvard@appliance (~/Dropbox/hacker2): ./initials
Zamyla Chan
ZC
jharvard@appliance (~/Dropbox/hacker2): ./initials
robert thomas bowden
RTB
2.
Аве, Цезарю!
Згадаємо коротке відео від David DiCiurcio, де розповідається, що шифр Цезаря полягає в тому, щоб циклічно зсунути алфавіт на деякий ключ, який становить кількість літер на які робиться зсув (можете порівняти з http://en.wikipedia.org/wiki/Caesar_cipher). Іншими словами, якщо р - деякий звичайний текст (тобто незашифрований), pi - i-й символ в р, a k -ключ (невід’ємне ціле число), то кожна літера, ci, в шифрованому тексті c, обчислюється таким чином:
ci = (pi + k) % 26
Може здатися, що ця формула робить шифр складнішим, ніж він є насправді, але це лише гарний шлях точного та стислого вираження алгоритму. А вчені таке люблять.
Наприклад, припустимо, що є секретний ключ k = 13 та звичайний текст р: "Be sure to drink your Ovaltine”. Давайте зашифруємо p та k, щоб отримати шифр c зі зміщенням кожної літери тексту p на 13 позицій
Be sure to drink your Ovaltine!
отримаємо:
Or fher gb qevax lbhe Binygvar!
Ми навмисно вивели все шифром, з одноковою шириною літер, щоб все виглядало гарно. Зверніть увагу на те, що літера
O
(перша літера в зашифрованому тексті) зміщена на 13 позицій від літери B
(перша літера в незашифрованому тексті). Так само й r
(друга в зашифрованому тексті) на 13 більша за e
(друга в незашифрованому тексті). В той же час, літера f
(третя літера в зашифрованому тексті ) на 13 позицій більша за s
(третя літера в початковому тексті), в цьому випадку ми переходимо по кругу від z
до a
. І так далі. Не надто безпечний шифр, але цікавий для реалізації!Між іншим, шифр Цезаря з ключем 13, як правило, називають
ROT13
(http://en.wikipedia.org/wiki/ROT13). Насправді, краще використовувати ROT26,
який, як вважають, в два рази безпечніший. У всякому разі, ваша наступна ціль полягає в тому, щоб написати в caesar.c
програму, що шифрує повідомлення за допомогою шифру Цезаря. Програма
повинна приймати один аргумент командного рядка: невід'ємне ціле число.
Давайте назвемо його k
. Якщо вашу програму запускають без
будь-яких даних командного рядка, або з більш, ніж одним аргументом,
повинно з’являтись повідомлення про помилку і повертатися значення 1
(що в даному випадку означає помилку) як вказано нижче:return 1;
В іншому випадку, програма повинна перейти до запиту тексту, який потрібно зашифрувати; символи, які не є літерами алфавіту, будуть виведені без змін. Після виведення зашифрованого тексту програма повинна завершитися,
main
має повернути 0
наступним чином:return 0;
Якщо ви явно не повертаєте
int
всередині main,
0
фактично повертається автоматично (насправді, так як це "тип значення, що повертається", main
має повертати значення типу int,
але про це іншим разом). Тепер, коли ви повертаєте 1
явно, найкраще буде повертати 0
(якщо все правильно) в явному вигляді для успішного виконання програми. В той час, як 0
в загальному випадку демонструє успіх, будь-яке інше значення int
являє собою помилку. Таким чином, ви можете представити понад чотири мільярди варіантів помилок, так як int
, як правило, 32 бітний!У всякому разі, не дивлячись на те, що існує тільки 26 літер в англійському алфавіті, ви не можете припустити, що
k
буде меншим або рівним 26
; ваша програма повинна працювати зі всіма невід'ємними цілочисельними значеннями k
меншими за 231 - 26. Іншими словами, вам не потрібно турбуватися, що програма врешті-решт зламається, коли користувач вибере значення k
, що буде занадто велике, щоб поміститися в int.
Тепер, навіть якщо k
більше, ніж 26, літери будуть залишатися літерами. Наприклад, якщо k
= 27, A не стане символом [
, навіть якщо[
знаходиться на 27 місці від A
в таблиці ASCII; A
перейде до B
, так як 27 по модулю 26 (остача від ділення 27 на 26) дорівнює 1. Іншими словами, k
= 1 та k
= 27 еквівалентні.Ваша програма має також враховувати, що при введенні великих літер вони повинні залишитися великим, а при введенні малих - малими.
З чого ж почати? Що ж, так як ця програма має стартувати з того, що в командному рядку вона повинна прийняти значення
k
, в main
треба прописати:int main(int argc, string argv[])
Нагадаємо, що
argv
- це масив рядків. Ви можете уявляти
масив, як ряд шафок в спортзалі, всередині кожної з яких знаходиться
деяке значення (наприклад, шкарпетки). В цьому випадку всередині кожної
такої шафки є string.
Щоб відчинити перший замок, ми використовуємо синтаксис argv[0]
, так як індексація масиву починається з 0
. Щоб відчинити наступний, ми звертаємося до нього argv[1]
. І так далі. Звісно, якщо ми маємо n
замків, то нам краще зупинитися на argv[n - 1]
, так як argv[n]
не існує! (Взагалі він існує, але належить комусь іншому, тому ви не повинні його чіпати.)Таким чином, ви можете отримати доступ до
k
так:string k = argv[1];
якщо припустити, що там щось насправді є! Нагадаємо, що
argc
має тип int
та дорівнює кількості рядків, що знаходяться в argv
, так що краще перевірити значення argc
перед відкриттям комірки, бо раптом її не існує! В ідеалі, значення argc
має бути 2. Чому? Що ж, нагадаємо, що всередині argv[0]
типово знаходиться власне ім'я програми. Так, argc
завжди буде не менше за 1. Але для цієї програми необхідно, щоб користувач надав аргумент k
, тому й argc
буде 2. Звичайно, якщо користувач вводить більше, ніж один аргумент до командного рядка, argc
може бути більшим за 2.Те, що користувач вводить ціле число в рядок, ще не означає, що внесене буде автоматично зберігатися в тип
int.
Навпаки, це значення буде збережене як string
, який лиш виглядає як int
! Так що ви повинні конвертувати string
в справжній int
. На щастя, існує функція atoi
, яка й створена для таких цілей. Вона застосовується наступним чином:int k = atoi(argv[1]);
Зверніть увагу, що на цей раз ми оголосили
k
як справжній int,
так що ви можете зробити деякі арифметичні дії з ним. Ось, вже набагато
краще. Між іншим, можна припустити, що користувач буде вводити лише
цілі числа. Вам не доведеться думати про них, оскільки ввівши, скажімо, foo, atoi
поверне 0
.Оскільки
atoi
оголошена в stdlib.h
, потрібно прописати #include
на початку коду. Технічно, ваш код компілюватиметься без нього, так як ми вже включили його до cs50.h
. Але краще самостійно звикати підключати потрібні бібліотеки.Отже, як тільки ви отримали
k
, що зберігається як int,
потрібно зробити запит для отримання звичайного тексту. CS50’s має функцією GetString,
яка може допомогти з цим.Після того, як у вас є
k
та деякий початковий текст,
можна приступати до шифрування. Нагадаємо, що ви можете перебирати та
надрукувати всі символи в рядку, створивши цикл:for (int i = 0, n = strlen(p); i < n; i++)
{
printf("%c", p[i]);
}
Іншими словами, так само, як
argv
є масивом рядків, string
є масивом символів. І тому можна використовувати квадратні дужки для
доступу до окремих символів рядка так само, як отримувати окремі рядки в
argv.
Звичайно, друк кожного з символів не є шифруванням. Тільки, за умови, коли k
= 0. Але ж ми маємо допомогти Цезарю зашифрувати його лист! Аве, Цезар!Між іншим, потрібно підключити ще один файл, щоб використовувати
strlen.