Всем, доброго, с вами Мирра Андрюхан. В прошлой статье мы с вами разобрались с первой частью грамматики Си/Си++. Разобравшись с основными моментами Си/Си++ и типами данных, мы также поняли, как объявляют, определяют и инициализируют переменные. После этого у вас, врядли возникнут проблемы по созданию переменных, если конечно вы не пытаетесь освоить что-то новое и у вас, разумеется не все сразу получается. Например, такое может быть с определением и инициализацией объекта класса, где объект это переменная, но об этом либо позднее, либо в следующем цикле статей.
А теперь, предлагаю, разобраться в работе основных операторах языка программирования Си/Си++ и работе с функциями. Этого, с лихвой хватает на уровне начинающего в программировании на Си/Си++. И не забывайте, давать себе времени на прочтение, т.к. эти статьи залпом лучше не читать, иначе толку будет меньше. К тому же, на этот раз примеры будут в каждой части статьи, а не как в прошлой, т.е. теории и практики будет в равных пропорциях. А также полагаю, что вы применяете на ОС Линукс указанные примеры, чтобы самолично удостовериться в результате выполнения программ, а не просто пролистать. Практика, всегда полезна.
Введение.
Само понятие функции возникло задолго до появления операторов, т.к. в те времена вызов нужного куска программы был важнее, а операторов еще не было. Можно, сказать, что не было и ПК в привычном виде. А если операторы были, то только простые, но все это времена ассемблера. И в ассемблере к тому же, можно было вызвать подпрограмму, которая была, либо процедурой, либо функцией, причем функция могла принять аргументы и вернуть значения. Однако, времена шли, потребности росли и менялись, и со временем появились формальные языки высокого уровня, например такие как Си. А Си стал включать в себя такие операторы, как: оператор присвоения, математический оператор, логический оператор (булева логика, математическая логика), оператор преобразования типов данных, операторы адресации и прочие операторы.
Понимаю, что операторов что-то многовато для начинающего, но это только основные операторы, есть еще операторы для работы с классами и объектами и т.д. с миру по нитке. Но о них, мы либо не будем упоминаться, либо позднее в данном цикле статей, т.к. еще в начале данного цикла статей мы определили предел обучения, направление и цель, для которой все это рассказываем. Как говорится обо все не расскажешь за один заход, как ни пытайся. Однако, для расширения кругозора тут будут предъявлены большинство операторов языка Си/Си++, которые могут когда-нибудь пригодиться.
Математические операторы
Данные операторы в особом пояснении не нуждаются, поэтому предлагаю посмотреть на наглядный пример ниже. Однако, обратите внимание, декремент и инкремент. И в тоже время, не забывайте что остаток от целочисленного деления не выполняется с численными типами данных с плавающих запятой, для них есть отдельные функции в стандартных библиотеках. Но, об этом в следующей статье.
1 2 3 4 5 6 7 8 9 10 |
finalsborki: programma clean programma: programma.o g++ programma.o -o programma programma.o: programma.cpp g++ -c programma.cpp clean: rm *.o |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include <stdio.h> int main(){ int i = 0, a = 3, b = 2;//задаем несколько переменных, одной строкой i = a + b;// оператор сложения printf("%d", i); printf("%s", "\n"); i = a - b;// оператор вычитания printf("%d", i); printf("%s", "\n"); i = a * b;// оператор умножения printf("%d", i); printf("%s", "\n"); i = a / b;// оператор деления printf("%d", i); printf("%s", "\n"); i = a % b;// оператор по модулю, который возвращает целоцисленный остаток //для работы с типами данных с плавающей запятой, применяется функция modf и // fmod из стандартной библиотеки, но об этом позднее printf("%d", i); printf("%s", "\n"); i = 2 + 2 * 2;// Как думаете компилятор Си знает правила // сложения и умножения? Что будет, 6 или 8?! printf("%d", i); printf("%s", "\n"); //А теперь результат будет таким, который многие говорят наобум i = (2 + 2) * 2; printf("%d", i); printf("%s", "\n"); i = 0;// обнулим работу с переменной i для демонстрации следующих операторов printf("%d", i); printf("%s", "\n"); //так работает префиксный инкремент, самый распространенный в применении a = ++i;// сначала увеличивает, а потом присваивает значение printf("%s", "a = "); printf("%d", a); printf("%s", " i = "); printf("%d", i); printf("%s", "\n"); //так работает постфиксный инкремент a = i++;// сначала присваивает значение, а потом увеличивает printf("%s", "a = "); printf("%d", a); printf("%s", " i = "); printf("%d", i); printf("%s", "\n"); //так работает префиксный декремент, самый распространенный в применении a = --i;// сначала уменьшает, а потом присваивает значение printf("%s", "a = "); printf("%d", a); printf("%s", " i = "); printf("%d", i); printf("%s", "\n"); //так работает постфиксный декремент a = i--;// сначала присваивает значение, а потом уменьшает printf("%s", "a = "); printf("%d", a); printf("%s", " i = "); printf("%d", i); printf("%s", "\n"); //Возвращаем ноль, чтобы не возвращать кодов ошибки. return 0; } |
Как собирать пример выше, вы уже знаете, поэтому объяснять не стану, если что смотрите в начале статьи по ссылке на прошлые статьи из данного цикла статей. И далее в этой статье мы не будем упоминать исходный код файла «makefile», т.к. он останется без изменений.
Логические операторы
Также в особом представлении не нуждаются, поэтому посмотрим все в примере ниже.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#include <stdio.h> int main(){ int a = 3, b = 2;//задаем несколько переменных, одной строкой bool l1 = false, l2 = true; l1 = a == b;// оператор сравнения равно printf("%s", l1 ? "истина" : "ложь"); printf("%s", "\n"); l1 = a != b;// оператор сравнения не равно printf("%s", l1 ? "истина" : "ложь"); printf("%s", "\n"); l1 = a > b;// оператор сравнения больше printf("%s", l1 ? "истина" : "ложь"); printf("%s", "\n"); l1 = a < b;// оператор сравнения меньше printf("%s", l1 ? "истина" : "ложь"); printf("%s", "\n"); l1 = a >= b;// оператор сравнения больше или равно printf("%s", l1 ? "истина" : "ложь"); printf("%s", "\n"); l1 = a <= b;// оператор сравнения меньше или равно printf("%s", l1 ? "истина" : "ложь"); printf("%s", "\n"); l1 = !l2;// оператор логическре НЕ printf("%s", l1 ? "истина" : "ложь"); printf("%s", "\n"); l1 = l1 && l2;// оператор логическре И printf("%s", l1 ? "истина" : "ложь"); printf("%s", "\n"); l1 = l1 || l2;// оператор логическре ИЛИ printf("%s", l1 ? "истина" : "ложь"); printf("%s", "\n"); l1 = 3+2 < 2 ? true : false; //оператор условия в выражении //в случае истины выражения присваивает первое значение, //иначе второе значение //для примера обратите внимание на функцию printf во всем исходном коде printf("%s", l1 ? "истина" : "ложь"); printf("%s", "\n"); //Возвращаем ноль, чтобы не возвращать кодов ошибки. return 0; } |
Операторы адресации и преобразования типов
Операторы адресации передают ссылку на переменную для передачи ее указателю или ссылке в качестве аргумента функции. В таком варианте ссылки вам пригодятся чаще всего, при работе с функциями из стандартной библиотеки, поэтому мы о них упомянем в этой статье. А также, преобразование типов работает в том случае, если значение переменной в нынешнем типе данных не выходит за пределы значений, а также известно компилятору Си/Си++ о том, как преобразовывать определенный тип данных. К тому же компилятор изначально знает, как приводить основные типы данных, чего не скажешь о классах в Си++. В этом, случае такие допустимые преобразования прописываются в самом классе, тогда преобразование работает. В обще-то вы можете не замечать, когда преобразование типов может сработать, это нормально на вашем уровне развития. Просто, раскладывайте выражение с преобразованием в несколько строк выражений и проверяйте каждую часть при отладке программы. А теперь, давайте посмотрим на пример.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <stdio.h> #include <cmath> int main(){ double d1 = 2.32445, d2 = 0, d3 = 0;//задаем несколько переменных, одной строкой float f1 = 0; d3 = modf(d1, &d2);//оператор & передает адресс переменной указателю printf("%f", d1); printf("%s", "\n");//выводим число printf("%f", d2); printf("%s", "\n");//выводим целую часть числа printf("%f", d3); printf("%s", "\n\n");//выводим дробную часть числа f1 = (float) d1;//явное преобразование типа данных printf("%f", f1); printf("%s", "\n"); f1 = d3;//неявное преобразование типа данных printf("%f", f1); printf("%s", "\n"); //Возвращаем ноль, чтобы не возвращать кодов ошибки. return 0; } |
Оператор присвоения
Оператор присвоения выполняет заполнение переменной итоговым значением выражения справа, при этом некоторые присваивания могут иметь сокращенный вид. Например, как это видно в примере.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <stdio.h> int main(){ int i1 = 0, i2 = 2, i3 = 3; int i4 = 2, i5 = 3; i1 = i2;// оператор присвоения printf("%d", i1); printf("%s", "\n");//результат оператора присвоения i2 += i3;//оператор присвоения сложения printf("%d", i2); printf("%s", "\n");//результат оператора присвоения i4 = i4 + i5;//тоже самое, что и выше printf("%d", i4); printf("%s", "\n");//результат оператора присвоения //Возвращаем ноль, чтобы не возвращать кодов ошибки. return 0; } |
Приоритеты выражений.
В принципе в приоритетах выражений в Си/Си++ нет ничего сложного. Достаточно помнить, вызовы функций и круглые скобки выполняются первыми, а потом все остальное. При этом, математика выполняется как принято в математике, а в математической логике в принципе также, но сначала выполняются скобки и логическое «НЕ», а уже потом логическое «И» и после логическое «ИЛИ», а знаки сравнения равно и т.д. выполняются последними. Так, что скобками мы повышаем приоритет выполнения части выражения.
И да, по сути как ранее упоминалось в основных моментах Си/Си++, вы основном пишете исходный код выражениями, которые всегда заканчиваются знаком «;». А компилятор их переводит в понятных компьютеру язык исполнения программного кода.
А теперь, посмотрим наглядный пример.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <stdio.h> int main(){ int i = 0; bool l = false; i = (2 + 2) * 2;//в данном случае будет равно восьми, а не шести printf("%d", i); printf("%s", "\n"); l = !(true && false) == true;//логическое выражение будет истинно printf("%s", l ? "истина" : "ложь"); printf("%s", "\n"); //Возвращаем ноль, чтобы не возвращать кодов ошибки. return 0; } |
Помимо обычных и простых операторов в языке программирования Си/Си++ есть еще оператор условия и операторы цикла.
Оператор условия
Оператор условия из себя не представляет ничего сложного, достаточно помнить что это оператор ветвления алгоритма, т.е. при выполнении логического выражения выполняется одна часть исходного кода, в противном случае другая. Например, как это видно на примере ниже.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include <stdio.h> int main(){ int i = 5; if (i >= 5) //простое условие if с одним выражением printf("%s", "истина");//выполнение в случае истина if (i <= 5) //простое условие if с одним блоком выражений { printf("%s", "\n"); printf("%s", "истина");//выполнение в случае истина printf("%s", "\n"); }; if (i < 5) //условие if с одним выражением printf("%s", "\nистина");//выполнение в случае истина else printf("%s", "\nложь");//выполнение в случае ложь if (i > 5) //условие if с блоками выражений {//выполнение в случае истина printf("%s", "\n"); printf("%s", " истина"); } else {//выполнение в случае ложь printf("%s", "\n"); printf("%s", "ложь"); }; //Продолжение выполнение алгоритма printf("%s", "\n"); //Возвращаем ноль, чтобы не возвращать кодов ошибки. return 0; } |
Операторы цикла
Всего операторов цикла в языке программирования Си/Си++, три. Это перечисление численной переменной и два цикла с условием, причем первый сначала проверяет условие, а потом выполняет, а второй сначала выполняет, потом проверяет условие на выполнение.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#include <stdio.h> int main(){ int i; for (i = 0; i < 5; i++) { printf("%d", i); printf("%s", "\n"); } for (i = 0; i < 5; i++) printf("%d", i); //Продолжение выполнение алгоритма printf("%s", "\n"); i = 0;//сначала проверка, потом выполнение тела цикла, пока условие истинно while (i < 5) { printf("%d", i); i++; } //Продолжение выполнение алгоритма printf("%s", "\n"); i = 0;//сначала выполнение, потом проверка условия продолжения цикла do printf("%d", i++); while (i < 5); //Продолжение выполнение алгоритма printf("%s", "\n"); i = 0; do {printf("%d", i++);} while (i < 5); //Продолжение выполнение алгоритма printf("%s", "\n"); i = 0; while (true)//будьте аккуратны с бесконечными циклами { if (i++ < 5) continue; //переходит к следующей итерации цикла else break; //прерывает выполнение цикла //выполнение цикла, который не выполнится из-за условия выше printf("%s", "\nСтрока"); } //Возвращаем ноль, чтобы не возвращать кодов ошибки. return 0; } |
Функция в языке программирования Си/Си++
Функции в Си/Си++ тоже не так уж сложны, как это может показаться и они очень часто применяются в программировании, как на Си, так и в Си++.
Для создания функции, необходимо задать возвращаемое ею значение, имя самой функции и в круглых скобках перечислить принимаемые аргументы через запятую, а уже потом в фигурных скобках написать выполнение функции, причем завершение функции будет оператор «return», как это показано на примере ниже.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include <stdio.h> //Функция с возвращением значения int privetmir(int i){ char stroka[] = "Привет, Мир!\n"; printf("%s", stroka); return i; } //Функция, которая не возвращает значение, но тоже выполняется void privet(){ char stroka[] = "Привет, Мир!\n"; printf("%s", stroka); } int Summa(int x1, int x2) { return x1 + x2;} //это тоже фукнция, к тому же обязательная для создания программы, т.к. основная int main(){ //вызов функции privetmir(5); //вызов с передачей значения переменнойж int i = 3; privetmir(i); //вызов с возвратом значенияж int k = 0; k = privetmir(i); //вызов простой функции privet(); //Функция Summa возврщает числовое значение, которое применяется аргументом //для функции printf printf( "%d", Summa(4, 5) ); printf("%s", "\n"); //Возвращаем ноль, чтобы не возвращать кодов ошибки. return 0; } |
Также напомню, что исходный код, который повторяет два и более раз, рекомендуют переносить в отдельную функцию. А также напомню, что срок жизни переменных определенных в функции, ее же и ограничиваются.
Этого достаточно знать по части грамматики в языке Си/Си++, чтобы применять язык программирования для самоизучения его по любым книжкам по нему, например по такой. Понимаю, не этого вы от меня ожидали, но блог не является учебником, он только знакомит вас с языком и помогает сделать первые шаги в этом деле.
В заключение
По грамматике языка программирования Си/Си++ можно много чего сказать, но это выходит далеко за пределы ведения сие блога. Однако, напомню вам о том, что полезно еще раз прочесть про основные моменты в Си/Си++ в прошлой статье и посмотреть на пример ниже.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <stdio.h> void privetmir(){ int i = 0; while (i < 10) { if (i == 0) printf("%s", "Привет, Мир! В первый раз!\n"); if (i>0 && i<4) printf("%s%d%s", "Привет, Мир! ", i + 1," раза!\n"); if (i == 4) printf("%s", "Привет, Мир! В пятый раз!\n"); if (i >= 5) printf("%s%d%s", "Привет, Мир! ", i + 1," раз!\n"); i++; } } int main(){ privetmir(); //Возвращаем ноль, чтобы не возвращать кодов ошибки после выполнения программы. return 0; } |
Поздравляю вас с прохождением основных моментов в грамматике языка программирования Си/Си++. Теперь, вы можете браться за любой учебник по этому языку, что для школьников, что для студентов и программировать в свое удовольствие. Теперь, вы знаете все, что вам нужно. Однако, в следующей статье мы с вами пройдемся по основным моментам установки и удаления программ созданных языком программирования Си/Си++.