Оглавление:
Все вопросы/пожелания обязательно оставляйте в этой теме, я постараюсь на них ответить
Доброго тебе времени суток, мой дорогой любознательный друг =) В своих статьях я постараюсь дать те базовые знания, которые трудно почерпнуть из литературной массы самостоятельно, поделюсь своим скромным опытом и постараюсь передать те базовые принципы и творческое мышление, в котором нуждается каждый человек, видящий себя в ИТ сфере.
Начнём, пожалуй, с перечня правил, которые могут пригодиться в будущем:
0. В любой непонятной ситуации, при всех условиях и в каждом из параллельных измерений отсчёт в языке C++ ведётся от НУЛЯ. Очень часто из-за такой мелочи на ранних этапах возникает много сумбура
1. Все кодеры пишут говнокод! Абсолютно все.Говнокод пишу я, говнокод пишет DeviantUser, говнокодит Goodie, и, возможно, скоро начнешь говнокодить и ты) Стоит ли переживать по этому поводу? Абсолютно нет. Но ВАЖНО ОСТАВЛЯТЬ ГРЁБАННЫЕ КОММЕНТАРИИ, чтобы выползая из доты понимать, что за код ты писал месяц назад.2. Если что-то не получается:Если что-то не получается, ломаешь голову над происхождением непонятной тебе ошибки и никаких годных идей не приходит в голову - возьми перерыв. Сходи налей себе чашечку чая, подойди к окну, позалипай в небо, сделай гимнастику для глаз - что угодно, чтобы разгрузить мозг. Как человек курящий я берусь утверждать, что все озарения происходят именно в течение этого перерыва или после него3. Об этой теме:Я ни в коем случае не считаю себя единственным тру-кодером планеты и данная тема несёт в себе всего лишь моё личное понимание/заметки/советы. И я крайне надеюсь, что большая часть написанного окажется кому-то полезной/мотивирующей информацией =)
0.0 Hello world! - Вступительный урок
Соблюдая традицию, я предлагаю Вам разобрать следующий код:
Даже на таком базовом примере можно неплохо поживиться - очень ВАЖНО читать код и понимать, что происходит в процессе выполнения кода!
Результатом компиляции соответственно будет надпись Hello world! в окне cmd (В зависимости от используемого компилятора программа либо будет ожидать нажатия любой клавиши, либо же просто моргнёт на экране. Касательно второй ситуации напишу в конце этой статьи)
Постарайтесь следующий кусок информации воспринять максимально внимательно, он задаст модель рассуждений/мышления которая очень сильно пригодится в будущем, поверьте мне на слово)
Разберем построчно код, приведённый в качестве примера выше:
1: #include <iostream> Что делает данная строка? Любой, кто брался за литературу скажет: "Подключает файл библиотеки в программу". Но давайте копать глубже: Что есть #?
В языке С++ символ # ставится перед каждой командой препроцессору. Называется Директивой препроцессора
@username: А что такое препроцессор? М? Мм?Таким образом(читая свой код проговаривайте до тех пор, пока это не устаканится в голове как аксиома):
@me: Компиляция любого кода происходит поэтапно. Первой выполняется обработка команд препроцессора, например: #include "12345.hpp" даёт команду компилятору весь код из файла 12345.hpp разместить на месте данной директивы, дабы использовать этот код на следующих этапах компиляции
@username: А дальше какие этапы?
@me: Препроцессор выдаёт на выходе полный код всей программы (даже если в ней туева куча файлов), который проверяется на грамматические/математические/программные ошибки. Этот код преобразовывается в объектный модуль ".obj". Финальный этап: Компоновщик принимает объектный код, компонует его с зависимостями (библиотеки преимущественно) и формирует исполняемый файл ".exe" Именно exe и является конечным результатом Ваших стараний
<1: #include <iostream> - команда препроцессору включить указанный файл/библиотеку в данном месте программы
2: using namespace std;
Подключаем пространство имён std. Сейчас не вижу смысла останавливаться на этом более подробно, но кое-что всё таки стоит знать о пространствах имён. Пространства имён используются для избежания конфликта между идентичными функциями разных библиотек. Пространство имён подключается либо как в примере, либо напрямую перед функцией по следующей схеме пр.имён :: имя_функ т.е: std::cout<<"Как то так";
3: Самое вкусненькое! int main ( /* int argc, char *argv */){
На этом этапе кода декларируется основная функция в которой происходит вся магия нашей программы.
int main ( /* int argc, char *argv */){ Объявляем функцию main возвращающую целочисленное значение, { указывает на то, что далее следует тело (код) функции, который закончится обратной }
Важно понимать: Разница между ОБЪЯВЛЕНИЕМ и ИНИЦИАЛИЗАЦИЕЙ функций.
Объявление - мы говорим компилятору "Эй, алло, в моей программе будет функция ВЖУХ которая принимает такие-то аргументы и возвращает значение такого-то типа"
Инициализация: Сейчас я те расскажу, что делает функция ВЖУХ, амиго
Обращаю ваше внимание: Если вы попытаетесь использовать в коде функцию, которую не проинициализировали - получите ошибку компиляции. Функция должна быть объявлена ДО места использования. Инициализация может быть в любом месте программы.
Ну и еще немножко: /* и */ позволяют Вам оставлять многострочные комментарии в коде. Комментарии полностью игнорируются компилятором и служат только величию программистов
/* КОММЕНТ КОММЕНТ ЛАЙК
новая строка */
или
//всё что будет написано правее этих символов
//аналогично
В примере:Использую первый вариант комментариев чтобы убрать из компиляции аргументы функции main (ибо они нам в данный раз не нужны). argc и argv - позволяют передать в программу информацию из ОС Windows
4. cout<<"Hello world!";-тут всё просто: мы обращаемся к функции cout из библиотеки iostream, cout создаёт поток вывода, в который мы передаём строку "Hello world!", что собственно и увидим в окне выполнения
5. return 0;} Если мы указываем тип функции (ex. void) - то она ОБЯЗАНА вернуть значение, указанного типа (в нашем случае это int). Что и куда возвращает main в нашем примере? Это мэсседж операционной системе. 0 - означает успешное выполнение программы. не0 - возникновение ошибок в процессе исполнения. Ну и закрывающая фигурная скобка, сигнализирующая что на этом тело функции main заканчивается
Да-да, я сам был в шоке когда всё то-же самое объясняли мне) В любом случае речью это передать гораздо проще.
Давайте подведем небольшой итог:
- ВАЖНО на ранних этапах практики проговаривать каждую строчку кода. Это осядет в голове, Вам станет проще ориентироваться как в своём так и в чужом коде. Вы быстрее научитесь читать код так же как читаете книги
- МЫ РАЗОБРАЛИ в каком порядке происходит выполнение кода (для базы этого понимания более чем достаточно)
- УЗНАЛИ беглым образом о функциях, роли препроцессора, о включении стороннего кода в проект. На первые две темы мы поговорим более подробно в последующих уроках
- ВЫТЕРПЕЛИ эти 100500 букв и написали свой первый работающий код. Если это про тебя - Поздравляю! Теперь ты начинающий программист!
Чтобы окно выполнения "повисело" дабы вы разглядели результат: добавляем в программу две строки:
#include <Windows.h> в начале программы
Sleep(миллисекунд); перед return
0.1 Типы данных, оператор условия, циклы, практика
Продолжаем вброс информации в хаотичном порядке)Переменная:
Переменные и типы данных. Еще раз об объявлении/инициализации.
- Имеет уникальное имя-идентификатор (например CountOfMembers)
- Под переменную выделяется фиксированное количество памяти в зависимости от её типа (собс-но программа обращается к этой памяти по имени переменной)
Тип данных (встроенный):
- Определяет количество памяти, отводящееся под хранение данных
- Определяет возможные операции над данными
Всего встроенных типов пять:
- bool занимает в памяти 1 байт, логический тип (true/false или же истина/ложь; принимает численное значение от 0 до 255, где 0 = false, всё что не ноль=true)
- char занимает в памяти 1 байт, символьный тип, принимает значение от 0 до 255, где значение - код символа в таблице ASCII
- int занимает 4 байта, целочисленный тип, от -2 147 483 648 до 2 147 483 647
- float занимает 4 байта, числа с плавающей запятой (они же дробные), от -2 147 483 648.0 до 2 147 483 647.0
- double занимает 8 байт, числа с плавающей запятой (они же дробные), от -9 223 372 036 854 775 808 .0 до 9 223 372 036 854 775 807.0
В С++ также есть модификаторы встроенных типов:
- unsigned имя_типа(int/float/double) - исключает отрицательные значения, сдвигает правую границу значений в 2 раза дальше
- short int чаще всего используется именно в таком сочетании, значения от -32 768 до 32 767
- long имя_типа(int/float) - используется в тех случаях когда множества значений типа недостаточно (8 байт памяти для ваших астрономических чисел)
ВАЖНО: имеет место использование нескольких модификаторов сразу, например unsigned long int - беззнаковое целое астрономическое)
Минутка практики:
Пользуясь прошлым уроком напишите программу, используя следующий кусок кода:
На этапе объявления происходит выделение памяти под хранение значений переменных.
- В первой строке объявляются целочисленные переменные a и b. Инициализация этих переменных происходит в 3ей строке(присваивание значений)
- Во второй строке объявление-инициализация переменной x типа char
- В четвертой строке объявление-инициализация переменной логического типа bool (Пока на этой картинке она True - Goodie будет тут админом)
- В пятой строке объявление-инициализация переменной с плавающей запятой, значение взято из моей больной головы
Важно! Вы не можете и в принципе не должны использовать переменные до того, как присвоите им значение. Плодить переменные которые никогда не используются тоже не стоит.
Хорошим тоном написания кода (помимо комментариев) - выделять переменным понятные идентификаторы. В примере: a,b,x,n - шут знает что это и где используется. А вот GoodieAdmin сразу доставляет :)
Оператор условия if, Операторы сравнения, полезный switchПопробуем решить следующую задачку:
Лицеист-отличник Паша едет домой в автобусе и залипает в телефон. В автобус заходит пассажир и становится рядом с Пашей. Если пассажир девушка - Паша уступит место, иначе - нет. Проверить вводимую информацию (пол м или ж), выдать результат.
1. Напишем базовый кусок программы :#include <iostream> //подключаем библиотеку ввода-вывода(без нее никуда)
using namespace std; //пространство имён, писать каждый раз Std:: сложнее
int main(){ //Объявим и проинициализируем главную функцию нашей программы main
//Здесь произойдет вся магия
//Presto!
return 0; //Не забываем возвращать 0 (если код дошел до этого момента без ошибок то эт хорошо)
}2. Разберемся что нам нужно. Переменная для работы с вводимыми данными типа unsigned short int(полезная привычка выдавать переменным наиболее подходящий тип), код, проверяющий ввод и выдающий результат.
unsigned short int choose; //объявляем переменную целочисленного типа, в нее будем пихать всё что введет юзер
cout<< " Кто стоит рядом с Петей?"<<endl; //уже известная всем строка. endl отвечает за перевод каретки на след строку
cout<<"0 - Муж 1 - Жен \n"; // Как и endl "\n" является спец символом который переведет строку
cin>>choose; //Поток ввода, записываем введенную информацию с клавиатуры в переменную choose
Минутка теории:
Конструкция Если - то в с++ выглядит следующим образом :
if (условие) { операторы }else{ операторы }
Важно! Следующая конструкция тоже считается верной : if (условие) один_оператор;
Вернемся к нашему коду и воспользуемся оператором if
3. Итак, нам необходимо проверить что ввёл пользователь. Мы ожидаем от него единицу(0 - Муж) или (1 - жен). Воспользуемся конструкцией if:
if ( (choose != 0) && ( choose !=1) ) { // Дословно: Если (choose неравно (!=) 0 и(&&) choose неравно (!=) 1) то:cout <<"Ошибка ввода! Конец работы программы";} else { //данный участок выполнится если choose Равно 0 или 1
if(choose ==0) cout<<"Петя сам посидит \n"; //Если ввели 0 (муж), то Петя сидитif(choose ==1) cout <<"Петя уступает беременной девушке"<<endl; //Если ввели 1(жен), то Петя встаёт}
В принципе, задача решена.
Давайте познакомимся с таблицей наиболее часто используемых логических операторов:
Оператор сравненияСинтаксис РАВНО == НЕ РАВНО != БОЛЬШЕ > МЕНЬШЕ < БОЛЬШЕ ИЛИ РАВНО >= МЕНЬШЕ ИЛИ РАВНО <= ВспомогательныеСинтаксис НЕ ! И && ИЛИ ||
!!! ВАЖНО! Не путайте оператор равно (==) и оператор присваивания (=) !!!
Оператор ветвления switch
Часто приходится в зависимости от значения переменной выполнять тот или иной участок кода. В нашей задаче выше мы имели дело с 2мя возможными вариантами, но что если вариантов более 3?
В таких случаях очень помогает оператор Switch
Конструкция оператора switch выглядит следующим образом:switch (переменная) { //выбор среди значений переменныхcase значение1: //если переменная соответствует значению1операторы;break; //оператор завершающий работу c блоком Switch и продолжающий работу программы после }case значение2: //если переменная соответствует значению2операторы;break;......
......
......
case значениеN: //если переменная соответствует значениюNоператоры;default: //если переменная не соответствует ничему из того что выше. default можно не использовать если надобности в нем нет
break;
операторы;}
break;
На этом пожалуй и всё) В качестве самостоятельно-практического задания могу предложить вам написать простенький калькулятор =) Материала в данной теме для этого предостаточноЗадача: Написать программу-калькулятор. Пользователю предлагается меню, где он выбирает арифм действие (сложить/умножить/поделить/вычесть). После выбора действия вводится два числа и выдается результат на экран.
Подсказка: Можно добавить пятый пункт меню - завершение работы программы, а рабочий блок кода поместить в бесконечный цикл
while (choose!=значение) {
}