Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Уровень 13 (условное выражение)
Порядок: à Правило записи: e 1? e 2: e 3, где e 1, e 2, e 3 - выражения. Порядок выполнения: - вычислить e 1; - если e 1! = 0, то результат = e 2, иначе результат = e 3. Пример. a< b? 2*x: x/2 В языке Basic есть аналогичный оператор, работающий по тому же правилу. Правило записи: If ( e 1, e 2, e 3), где e 1, e 2, e 3 - выражения. Если e 1 = true , то результат = e 2, иначе результат = e 3. Пример. If (a< b, 2*x, x/2) Уровень 14 (операторы присваивания) Порядок: ß Правило записи: …[ e0 [< op > ]=] e 1[< op > ]= e 2 Здесь e 1 - переменная (простая или с индексами), которой задается значение e 2. e 2 - выражение. e 2 преобразуется к типу e 1 (если возможно). Запись < op > является необязательной и означает выполнение указанной операции над " старым" значением e 1 (в качестве второго операнда выступает e 2), а затем присваивание полученного " нового" значения переменной e 1. Допустимыми операциями являются: + - сложение, - – вычитание, * – умножение, / – деление, % – остаток, > >, < < – сдвиг вправо или влево, &, ^, | – поразрядные операторы. Пример. a*=5; // Это эквивалентно a=a*5; Замечание. Выражение x*=y+1 означает x=x*(y+1), а не x=x*y+1, поскольку уровень оператора *= ниже уровня оператора +. В комбинированных операциях значение e 1 вычисляется 1 раз, т.е. выражение a[i++]*=n; эквивалентно a[i]=a[i]*n; i=i+1; (постфиксный оператор ++ ), а выражение a[++i]*=n; - выражению i=i+1; a[i]=a[i]*n; (префиксный оператор ++ ). Оператор = может входить в состав выражения. Пример. while ((c=getchar())! =EOF){// Это означает посимвольное чтение //текстового файла до его окончания EOF ( End Of File ) – символическая константа, означающая конец файла и определенная в файле stdio.h. Переменная e 1 может быть указателем. Пример. int *x; ....... x+=2; // Изменяет значение x на 8 байтов Замечание. Не увлекайтесь сложными выражениями, пишите проще! Допустимо присваивание выражения e 2последовательнонескольким переменным (многократное присваивание). Пример. float x, y, z; short k; …………………. x=3.5; y=-2.7; z=k=x+=x+y; // x=4.3 k=4 z=4 z=4, поскольку присваивание выполняется по очереди справа налево. Порядок выполнения: x+y //=0.8 x+= //=4.3 k= //=4 k-целое, дробная часть отбрасывается z= //=4 В языке Basic допустимы такие же конструкции, кроме многократного присваивания, однако они являются инструкциями и, следовательно, не могут входить в состав выражения. Уровень 15 (оператор ', ' - запятая) Порядок: à Формат: e 1[, e 2]..., где e 1, e 2 - выражения. Результат имеет тип и значение самого правого выражения списка. Как правило, используется с выражениями, содержащими оператор присваивания. Весьма удобен при достаточно сложных инструкциях цикла. Пример. for (i=0, j=N-1; i< j; i++, j--){ // Одновременное изменение в одном цикле //переменных i и j в разных направлениях Некоторые замечания 1. При трансляции программы возможно переупорядочивание коммутативных или ассоциативных операторов. Если порядок вычисления важен, используйте промежуточные переменные. 2. В языке C не задан порядок вычисления операндов. При побочных эффектах результат машинно зависим. Побочным эффектом называют изменение значений аргументов функций. В выражении x = f ( x , y )+ g (& x , & y ); при перестановке слагаемых может измениться результат. 3. Также не фиксирован порядок вычисления аргументов функций. Пример. printf (" %d%d\n", ++n, pow(2, n)); // Результат неоднозначен 4. Не применяйте неоднозначных выражений. Чему равно, например, выражение a [ i ++] = i ++; ? Так не писать не следует!!! Постоянные выражения Постоянные выражения – это выражения, состоящие из литералов и символических констант. Они используются в таких конструкциях языка, как: - многоальтернативный выбор – инструкция switch, опция case; - границы массивов; - директивы препроцессора. Пример. # define SIZE1 500 # define SIZE2 500 # define PI 3.141593 # define PI2 2*PI ………………………. int a[SIZE1+SIZE2]; Вопросы для самопроверки и контроля Вопросы для самопроверки 1. Чему равно значение выражения sizeof (< имя_типа> )? 2. Какой тип должен иметь левый операнд оператора ->? 3. Дано: i=4; y=i++; x=++i. Чему равны значения i, y, x ? 4. Какой тип имеет результат выполнения унарного оператора &? 5. Что означают операторы = и == в языке C? Чей приоритет выше? 6. В чем отличие унарного и бинарного операторов &? 7. Какой оператор имеет 3 операнда? Контрольные вопросы 1. Требуется сформировать массив из отрицательных элементов другого массива. Правильно ли предложенное решение? float x[10], y[10], s; short i, k; for (s=k=i=0; i< 10; i++){ x[++k]=y[ i ]< 0? y[ i ]: 0; } 2. В чем отличие постфиксной и префиксной форм оператора ++? 3. Что означают операторы & и & &? 4. В чем смысл оператора " запятая"? 5. Дано: a=3; b=4; c=5; Чему равно выражение: a< b< c? 6. Где употребляются постоянные выражения? 12. ПЕРЕДАЧА ДАННЫХ ПОТОКОМ Этот раздел посвящен дополнительным консольным средствам ввода-вывода в языке C, используемых для ввода-вывода символьной информации. Функции scanf и printf и некоторые другие, о которых речь пойдет ниже, называют функциями передачи данных потоком. Это означает, что все данные, вводимые последовательными инструкциями scanf, образуют единый поток ввода, в котором начало и конец элемента данных определяются параметром соответствующей спецификации w или d либо специальными символами – ограничителями, внесенными в поток. Аналогично последовательность инструкций printf образует единый поток вывода. Проще всего данные каждого потока представить в виде непрерывной символьной строки. В языке определены 3 стандартных потока обмена данных: поток ввода stdin, поток вывода stdout и поток сообщений об ошибках stderr. По умолчанию поток stdin связан с клавиатурой, потоки stdout и stderr – с экраном монитора. На самом деле поток stdin также связан с экраном, поскольку большинство функций ввода отображают каждый вводимый с клавиатуры символ на экран. Точнее эти функции вставляют отображение вводимых символов в поток stdout. Это приводит к очереди за пользование ресурсом (экраном) и иногда к конфликтным ситуациям, описанным ранее. Замечание. Понятие потока не связано с конкретным языком программирования. Это свойство операционной системы. Количество потоков в приложении не ограничивается приведенными стандартными потоками, однако многопоточное программирование в данном курсе не рассматривается. Отметим, что рассмотренные в разделе 6 методы консольного ввода-вывода языка Basic также используют стандартные потоки: ReadLine – входной и выходной, Write и WriteLine – выходной. Отнесение данного материала к языку C связано с введением дополнительных функций для ввода-вывода строк, тогда как в языке Basic консольный обмен данных ограничим указанными 3-мя методами. 12.1. Спецификация " s" управляющей строки функций scanf и printf Предназначена для ввода-вывода символьных строк. Напомним, что в языке C определены только строковые литералы, которые представляют собой последовательность символов, завершающуюся нулевым символом. В качестве переменных применяются массивы типа char. Все функции ввода строк добавляют конечный нулевой символ. Ввод. Формат спецификации: % [w]s. Поле ввода ограничивается параметром спецификации w либо символами пробел или перевод строки (клавиша Enter ). Пример. %5s [Ивано]в // Будет введен текст, заключенный в [ ] Замечание. Ограничитель ввода остается в потоке и будет восприниматься последующими инструкциями ввода, что может привести к некоторым неожиданным последствиям. Например, следующая за функцией scanf функция gets, у которой символ перевод строки является ограничителем, может ввести пустую строку. Вывод. Формат спецификации: %[w][.d]s. Ограничителем является конечный нулевой символ либо параметр d спецификации. Пример. Выводимая строка имеет значение: " Привет, Коля! ". На экране получим: %s Привет, Коля! %.6s Привет Функции getchar и putchar Прототип: int getchar( ); - чтение одного символа с клавиатуры. Файл прототипа: stdio.h. Возвращаемое значение: символ (при успешном вводе)или EOF (ошибка ввода или конец файла). Признак конца файла при вводе: символы Ctrl + z. Прототип: int putchar( int ); - вывод одного символа на экран. Файл прототипа: stdio.h. Возвращаемое значение: символ (успех) | EOF (ошибка). Пример. // Чтение строки с терминала. // Возвращает указатель на строку и ее длину int getline( int lim, // Максимальная длина вводимой строки char *s){ // Вводимая строка char c; // Вводимый символ i nt i; fo r(i=0; i< lim & & (c=getchar())! =EOF & & c! ='\n'; i++){ s[ i ]=c; } s[ i ]='\0'; return i; } // End getline Функции gets и puts Прототип: char * gets( char *); - чтение строки символов. Файл прототипа: stdio.h. Возвращаемое значение: указатель на введенную строку (успех) | NULL - " пустой" указатель. Ограничитель ввода: символ перевод строки, который после ввода заменяется на конечный нулевой символ. Пример. char string[20]; ................ gets(string); Замечание. Можно включать в строку пробелы в отличие от спецификации s функции scanf. Прототип: int puts( char *); - вывод на экран строки символов. Файл прототипа: stdio.h. Возвращаемое значение: последний выведенный символ (успех) | EOF (конец файла). Замечание. Конечный 0 не выводится. В конец строки добавляется символ перевод строки. Рекомендация. Этим функциям следует предпочтение перед применением спецификации s функций scanf и printf по причинам: - позволяют выполнять ввод-вывод строк, содержащих пробелы; - gets удаляет за собой ограничитель ввода из потока. |
Последнее изменение этой страницы: 2017-04-12; Просмотров: 395; Нарушение авторского права страницы