Управление программным потоком Словарик Statement — the smallest independent computational unit; обычно переводят как инструкция или оператор. . . Instruction — инструкция; Operator — оператор; Expression — выражение; Declaration — декларация. Statements: int x; // declaration of variable int fun(int a); // declaration of function x = a+b; // expression Точка с запятой ; Признак конца оператора (end of statment): x = 0; ; // пустой оператор for(i=0; i<10; sum=i++); // тоже пустой оператор x = sin(a) // выражение можно + // разбить на cos(b); // несколько линий Фигурные скобки { ... } Используются для объединения описаний и операторов в составной оператор или блок (compound statment): if( a < b ) { a++; b−−; } Оператор if Простейший вариант: if (expression) { statement; } Полная конструкция: if (expression) { statement; } else { statement; } Пример: if (i < 10) { printf(" i less than 10\n"); } else { printf(" i greater than or equal to 10\n"); } Конструкция «выбор из нескольких вариантов»: if (expression) { statement; } else if (expression) { statement; } else if (expression) { statement; } else { statement; } Пример: if (i < 10) { printf(" i less than 10\n"); } else if (i <= 20) { printf(" i in the range of [10;20]\n"); } else { printf(" i greater than 20\n"); } Переключатель switch (выбор одного из многих вариантов) switch (expression) { case const_value_1: statement; case const_value_2: statement; case const_value_3: statement; default: statement; } Значение expression должно быть целым (int, char) После передачи управления на case программа выполняется до конца оператора switch Если выражение не совпадает ни с одним из case, то выполняется default: default: может отсутствовать int i = 0; printf("Enter an integer: "); scanf("%d",&i); switch(i) { case 1: printf("one "); break; case 2: printf("two "); break; case 3: printf("three "); break; case 4: printf("four "); break; default: printf("something else!"); } switch(i) { case 1: case 3: printf("is an odd number"); break; case 2: case 4: printf("is an even number"); break; } printf("\n"); Output: Enter an integer: 2 two is an even number Условный (троичный) оператор: (condition) ? (expression-true) : (expression-false) ; 1 Вычисляется condition 2 Если условие истинно (не ноль), то вычисляется expression-true, в противном случае expression-false 3 Вычисленное значение возвращается (оператор может стоять в правой части присваивания) Пример: int m = (n > 0) ? n : ... printf("the number %i ... int max(int a, int b) return (a > b) ? a } -n; are %s\n ",i,(i%2) ? "odd" : "even"); { : b; Циклы while while (expression) { statement; } цикл выполняется по тех пор пока expression не нулевое (истина) затем выполняется следующий за while оператор do – while do { statement; } while (expression); statement выполняется в любом случае далее выполняется также, как для цикла while Пример: while int age = 0; while(1) { printf(" please enter your age: "); scanf("%i", &age); if( age > 0 && age < 100 ) break; } printf(" age= %d \n",age); Пример: do – while int age = 0; do { printf(" please enter your age: "); scanf("%i", &age); } while( !(age > 0 && age < 100) ); printf(" age= %d \n",age); Цикл for «то же», что и конструкция: for(ExprIni; Cond; ExprIter) { statement; } ExprIni; while(Cond) { statement; ExprIter; } // // // // initial stmt. condition loop body «iteration» Стандартное выражение для обработки n элементов массива: for (i = 0; i < n; i++) { a[i] = ...; } Декларация переменных в ExprIni (C99) C99 допускает декларацию переменных в первом поле for: for (int i = 0; i < n; i++) {...} Область видимости этой переменной – весь цикл for При компиляции (версия gcc < 5) может потребоваться указать: gcc -std=c99 file.c Цикл for продолжение . . . Любое из трёх выражений в for можно оставить пустым, но разделители ( ; ; ) всегда должны присутствовать «Пустое» условие в for равносильно бесконечному циклу Бесконечный цикл: for (;;) {...} /* с циклом for */ while(1) {...} /* с циклом while: 1 == true */ // while() {...} /* ERROR! */ Для выхода из бесконечного цикла используют операторы перехода или return Оператор последовательного вычисления (запятая , ) expression1 , expression2 , expression3 , ... Выражения, разделённые запятой, вычисляются слева направо Возвращается значение правого (последнего) операнда Пример: x = (y=3, y+1); /* Лучше использовать: y=3; x=y+1; */ for(i = 0,j = 10; (i < 10) && (j > 0); i++,j--) {...} Внимание Запятые, разделяющие: либо аргументы функций, либо переменные в описаниях, не имеют отношения к операции запятая: // commas act as separators here, not as an operator: int a=1, i=0; double f(int x,int y); x += f(a,i); Операторы перехода Оператор break применяется в двух случаях: 1 2 В операторе switch с его помощью прерывается выполнение последовательности case Немедленно прекращает выполнение любого цикла Пример: for (i = 0; i < 5; i++) { for (j = 0; j < 5; j++) { if (j + i > 2 ) break; printf(" (%d, %d) ",i,j); } } Output: (0, 0) (0, 1) (0, 2) (1, 0) (1, 1) (2, 0) Оператор continue Прерывает текущую итерацию цикла и осуществляет переход к следующей итерации В цикле for переход на выполнение приращения (ExprIter) Пример: for (i = 0; i < 5; i++) { for (j = 0; j < 5; j++) { if (j + i < 6 ) continue; printf(" (%d, %d) ",i,j); } } Output: (2, 4) (3, 3) (3, 4) (4, 2) (4, 3) (4, 4) Безусловный переход: goto goto label; .... label: Для оператора goto всегда необходима метка – идентификатор с последующим двоеточием: label: Управление передается на ту точку программы, где стоит метка Метка может находиться как до, так и после оператора goto Пример: int i = 0; LOOP: a += b[i]; i++; if( i < 10 ) goto LOOP; /* сравните с do - while */ Старайтесь не использовать goto В структурном программировании goto рассматривают как крайне нежелательный оператор. «Качество программного кода обратно пропорционально количеству операторов goto в нём» (E.W. Dijkstra “Go to statement considered harmful”, 1968) «Спагетти-код» – программа содержащая много операторов goto Оправданное применение: Donald Knuth, “Structured Programming with go to Statements”, 1974 for( i = 0; i < n; i++ ) for( j = 0; j < m; j++ ) if( matrix[i][j] == value ) { printf("value %d found in cell (%d,%d)\n",value,i,j); goto end_loop; } printf("value %d not found\n",value); end_loop: ; Ввод/вывод. C – стиль Основные сведения: В языке С ввод/вывод делается при помощи библиотечных функций Объявление функций содержится в файле <stdio.h> Все эти функции прекрасно работают и в С++ Имеются как консольные (на экран) функции ввода/вывода, так и файловые Вывод на экран: Ввод с клавиатуры: printf(format, arg1, arg2, ...) scanf(format, arg1, arg2, ...) printf(format, arg1, arg2, . . . ) format – управляющая строка в двойных кавычках. Cодержит: обычные символы спецификаторы преобразования: % ...specifier управляющие символы: \n specifier d,i u o x,X f e,E g,G c s p \” \’ %% ... effect signed decimal unsigned decimal unsigned octal unsigned hexadecimal: 0-9,a-f (or A-F) double или float: 12.123456 double или float: 9.123456e-07 (or E) ≡ %e или %f (какой короче) один символ С-string печать указателей precision 1 1 1 1 6 6 не определено Модификаторы формата На месте точек в % ...specifier может стоять: + (знак плюс) – печать со знаком w.p – ширина вывода (w) и точность (p); − (знак минус) – выравнивании по левому краю модификатор длины переменной: sizeof specifier h short int dioux l(ell) long int dioux ll(ell-ell) long long int d i o u x L long double efg Управляющие символы \" \a \r \t double quote alert (BEL) carriage return horizontal tab \\ \b \n %% backslash backspace new line a single % scanf(format, arg1, arg2, . . . ) Обратите внимание функции scanf() необходимо передавать адреса (знак & перед переменными обязателен) обычные символы в format проверяются на совпадение с входным потоком и в случае не совпадения чтение прекращается значения спецификаторов не полностью совпадают с printf: – %i – читает целое число как в десятичном, так и восьмеричном или шестнадцатеричном формате – %f %e %g – соответствуют данным типа float %lf %le %lg – для double %Lf %Le %Lg – для long double Пример: #include <stdio.h> int main() { int age = 0; for(;;) { /* infinite loop */ printf(" please enter your age: "); scanf("%i", &age); if( age > 0 && age < 100 ) break; printf(" age should be in the range from 1 to 100\n"); } printf(" age= %d \n",age); } Output: please enter your age: 0 age should be in the range from 1 to 100 please enter your age: 0x5a age= 90