
- •Определение по Шеннону
- •Создание первых компьютеров
- •События, предшествовавшие появлению персональных компьютеров
- •Устройства для вывода визуальной информации
- •История Ранние разработки
- •Известные компиляторы языка Си
- •Данные плавающего типа
- •Переменные перечислимого типа
- •Массивы
- •Структуры
- •Объединения (смеси)
- •If (условие) оператор
- •If (условие) оператор1 else оператор2;
- •Оператор switch
- •Оператор for
- •1.4.8. Оператор while
- •1.4.9. Оператор do while
- •Функции с параметрами.
- •Передача параметра по значению
- •Передача параметра по адресу
- •Передача параметра по ссылке
- •Чтение из потока при помощи fgetc
- •При помощи fgets
- •Запись в файл при помощи fwrite
- •Запись в поток при помощи fputc
Структуры
Cтруктуры - это составной объект, в который входят элементы любых типов, за исключением функций. В отличие от массива, который является однородным объектом, структура может быть неоднородной. Тип структуры определяется записью вида:
struct { список определений }
В структуре обязательно должен быть указан хотя бы один компонент. Определение структур имеет следующий вид:
тип-данных описатель;
где тип-данных указывает тип структуры для объектов, определяемых в описателях. В простейшей форме описатели представляют собой идентификаторы или массивы.
Пример:
struct { double x,y; } s1, s2, sm[9];
struct { int year;
char moth, day; } date1, date2;
Переменные s1, s2 определяются как структуры, каждая из которых состоит из двух компонент х и у. Переменная sm определяется как массив из девяти структур. Каждая из двух переменных date1, date2 состоит из трех компонентов year, moth, day. >p>Существует и другой способ ассоциирования имени с типом структуры, он основан на использовании тега структуры. Тег структуры аналогичен тегу перечислимого типа. Тег структуры определяется следующим образом:
struct тег { список описаний; };
где тег является идентификатором.
В приведенном ниже примере идентификатор student описывается как тег структуры:
struct student { char name[25];
int id, age;
char prp; };
Тег структуры используется для последующего объявления структур данного вида в форме:
struct тег список-идентификаторов;
Пример:
struct studeut st1,st2;
Использование тегов структуры необходимо для описания рекурсивных структур. Ниже рассматривается использование рекурсивных тегов структуры.
struct node { int data;
struct node * next; } st1_node;
Тег структуры node действительно является рекурсивным, так как он используется в своем собственном описании, т.е. в формализации указателя next. Структуры не могут быть прямо рекурсивными, т.е. структура node не может содержать компоненту, являющуюся структурой node, но любая структура может иметь компоненту, являющуюся указателем на свой тип, как и сделано в приведенном примере.
Доступ к компонентам структуры осуществляется с помощью указания имени структуры и следующего через точку имени выделенного компонента, например:
st1.name="Иванов";
st2.id=st1.id;
st1_node.data=st1.age;
Объединения (смеси)
Объединение подобно структуре, однако в каждый момент времени может использоваться (или другими словами быть ответным) только один из элементов объединения. Тип объединения может задаваться в следующем виде:
union { описание элемента 1;
...
описание элемента n; };
Главной особенностью объединения является то, что для каждого из объявленных элементов выделяется одна и та же область памяти, т.е. они перекрываются. Хотя доступ к этой области памяти возможен с использованием любого из элементов, элемент для этой цели должен выбираться так, чтобы полученный результат не был бессмысленным.
Доступ к элементам объединения осуществляется тем же способом, что и к структурам. Тег объединения может быть формализован точно так же, как и тег структуры.
Объединение применяется для следующих целей:
- инициализации используемого объекта памяти, если в каждый момент времени только один объект из многих является активным;
- интерпретации основного представления объекта одного типа, как если бы этому объекту был присвоен другой тип.
Память, которая соответствует переменной типа объединения, определяется величиной, необходимой для размещения наиболее длинного элемента объединения. Когда используется элемент меньшей длины, то переменная типа объединения может содержать неиспользуемую память. Все элементы объединения хранятся в одной и той же области памяти, начиная с одного адреса.
Пример:
union { char fio[30];
char adres[80];
int vozrast;
int telefon; } inform;
union { int ax;
char al[2]; } ua;
При использовании объекта infor типа union можно обрабатывать только тот элемент который получил значение, т.е. после присвоения значения элементу inform.fio, не имеет смысла обращаться к другим элементам. Объединение ua позволяет получить отдельный доступ к младшему ua.al[0] и к старшему ua.al[1] байтам двухбайтного числа ua.ax .
Тип void Тип void (пустой) синтаксически ведет себя как основной тип. Однако использовать его можно только как часть производного типа, объектов типа void не существует. Он используется для того, чтобы указать, что функция не возвращает значения, или как базовый тип для указателей на объекты неизвестного типа. void f() // f не возвращает значение void* pv; // указатель на объект неизвестного типа Переменной типа указатель на void (void *), можно присваивать указатель любого типа. На первый взгляд это может показаться не особенно полезным, поскольку void* нельзя разименовать, но именно это ограничение и делает тип void* полезным. Главным образом, он применяется для передачи указателей функциям, которые не позволяют сделать предположение о типе объекта, и для возврата из функций нетипизированных объектов. Чтобы использовать такой объект, необходимо применить явное преобразование типа. Подобные функции обычно находятся на самом нижнем уровне системы, там, где осуществляется работа с основными аппаратными ресурсами. Например: void* allocate(int size); // выделить void deallocate(void*); // освободить f() (* int* pi = (int*)allocate(10*sizeof(int)); char* pc = (char*)allocate(10); //... deallocate(pi); deallocate(pc); *)
Функция - это самостоятельная единица программы, созданная для решения конкретной задачи. Функция в языке С играет ту же роль, что и подпрограммы или процедуры в других языках. Функциями удобно пользоваться, например, если необходимо обработать один и тот же код программы. Как и переменные, функции надо объявлять (declare). Функцию необходимо объявить до её использования. Запомните это простое правило - сначала объяви, а потом используй. Каждая функция языка С имеет имя и список аргументов (формальных параметров). Функции могут возвращать значение. Это значение может быть использовано далее в программе. Так как функция может вернуть какое-нибудь значение, то обязательно нужно указать тип данных возвращаемого значения. Если тип не указан, то по умолчанию предполагается, что функция возвращает целое значение (типа int). После имени функции принято ставить круглые скобки (это касается вызова функции её объявления и описания). В этих скобках перечисляются параметры функции, если они есть. Если у функции нет параметров, то при объявлении и при описании функции вместо <список параметров> надо поставить void - пусто. Основная форма описания (definition) функции имеет вид: тип <имя функции>(список параметров) { тело функции }
Арифметические операции языка Си. Операции инкремента и декремента.
Оператор - это действие или команда, которую может выполнить компьютер (вернее просто язык программирования). Операнды - это данные, необходимые для выполнения оператора рассматриваемого языка. Программа это запись алгоритма на языке компьютера (на языке программирования).
Арифметические операции и их особенности в языке С. В языке С к арифметическим операциям относятся следующие операции:
- вычитание или унарный минус;
+ сложение;
* умножение;
/ деление;
% деление по модулю;
++ увеличение на единицу; Инкремент. Префиксная: а++.
-- уменьшение на единицу; Декремент Постфиксная: --а.
Операции сложения, вычитания, умножения и деления действуют так же, как в большинстве алгоритмических языков программирования. операции выполняются так: сначала вычисляется значение левого выражения (операнда), затем вычисляется значение выражения, стоящего справа от знака действия. Далее, в том случае, когда операнды имеют общий тип данных, этот же тип имеет и результат. Поэтому, если применяется деление "/" к целым числам, например, 11/3, то результат тоже будет целым, то есть в данном случае 3. А выражение 1/2 в этом случае будет равно нулю. Операция "%" деление по модулю дает остаток от целочисленного деления. Она может применяться к целочисленным переменным. Теперь решим небольую задачу.
Операции отношения и логические операции языка Си.
Язык С имеет ровно шесть операции отношения. Почему их так называют? Дело в том, что обычно относительно двух величин, например, величины А и величины В, можно с определенностью сказать, что друг по отношению к другу они: или равны, то есть находятся в отношении равенства А=В, или не равны, то есть находятся в отношениях неравенства А не = В. Но тогда в последнем случае можно уточнять и думать уже о том, какая из этих двух величин больше и какая меньше. Тут может быть одна из двух возможностей: либо А<В, либо А>В. Иногда еще рассматривают такое отношение, в котором есть доля неопределенности, например, когда говорят, что А<=В, либо, когда А>=В. Сведем эти соотношения между двумя величинами в одну таблицу. Получим следующее:
"<" - меньше.
"<=" - меньше или равно.
">" - больше.
">=" - больше или равно.
"==" - равно.
"!=" - не равно.
Таким образом, А по отношению к В может быть: либо меньше, либо меньше или равно; либо больше, либо больше или равно; либо равно, либо не равно. Другого нам просто не дано.
Операции отношения используются в условных выражениях. Например, простейшие условия, которые не содержат логических операций, это следующие: "a<0", "1998>2003", "b==B", "C!=D" и так далее. Следует отметить, что относительно каждого условия решается вопрос: истинно оно или нет. В языке С отсутствует логический (boolean) тип. Поэтому при анализе истинности выражения, содержащего операции отношения, принято находить целочисленное арифметическое значение выражения. При этом считается, что истинность, то есть "true" соответствует ненулевому значению выражения. Обычно для "true" принято значение 1. Тогда 0 принимается за "false", то есть ложь.
Логические операции
Язык С имеет ровно три логические операции: это
&& или (AND);
|| или (OR);
! или (NOT).
Как принято еще называть логические операции?
Операция "&&" или операция "AND" называется еще операцией "и" или логическим умножением.
Операция "||" или операция "OR" называется еще операцией "или" или логическим сложением.
Операция "!quot; или операция "NOT" называется еще операцией "не" или логическим отрицанием.
Операция "&&" называется логическим умножением потому, что выполняется таблица истинности этой операции, очень напоминающая таблицу обыкновенного умножения из арифметики. Логическое умножение это такая операция, которая истинна тогда и только тогда, когда истинны оба входящих в нее высказывания. 1&&1=1 0&&1=0 1&&0=0 0 && 0 = 0
Операция "||" называется логическим сложением потому, что выполняется таблица истинности этой операции, очень напоминающая таблицу обыкновенного сложения из арифметики. Логическое сложение это такая операция, которая истинна тогда и только тогда, когда истинно хотя бы одно из входящих в нее высказываний. 1||1=1 0||1=1 1||0=1 0 || 0 = 0
Операция "!" называется логическим отрицанием потому, что выполняется следующая таблица истинности. Логическое отрицание это такая операция, которая истинна тогда и только тогда, когда ложно входящее в нее высказывание и наоборот. !1=0 !0 = 1
Кроме трех расмотренных выше классических логических операций в языке С используется еще четвертая логическая операция: "исключающее или". Если обычно принято операцию логическое умножение обозначать как "X AND Y", операцию логическое сложение как "X OR Y", а логическое отрицание как "NOT X", то операцию "исключающее или" обозначают как "X XOR Y". Сделаем одно очень выжное замечание. Оно касается логической операции XOR. В языке С нет знака логической операции XOR. Однако, она может быть реализована с помощью операций AND, OR и NOT. Покажем теперь таблицу истинности этой новой логической операции в языке С. 1XOR1=0 0XOR1=1 1XOR0=1 0XOR0=0 Отсюда видно, что, если оба входящих в выражение высказывания истинны или оба ложны, то есть однакового значения истинности, то результат будет в этом случае ложным. То есть как бы отрицается утверждение: оба высказывания имеют одинаковый смысл истинности. Напротив, если оба высказывания имеею разный смысл истинности, то в результате операции "исключающее или" это отрицается. Поэтому и выходит, что результат будет равен истине.
Приоритет выполнения логических операций. Логические операции и операции отношения имеют более низкий приоритет, чем арифметические операции. Это значит, что выражение 200>120+50 равносильно выражению 200>(120+50). Принято следующее старшинство операций отношения и логических операций: ! - самая старшая из логических операций Далее старшинство операций распределяется так: > < >= <= . Затем уже идут операции: == != и самая младшая операция - это ||. В логических выражениях можно использовать скобки, которые имеют наивысший приоритет. Это положение известно еще из арифметики. Оно сохраняется и здесь. Использование скобок делает выражение более понятным и удобным для чтения. Поэтому рекомекндуется использовать скобки. Условные и логические выражения часто используются в операторе условного перехода if и в других операторах. Отметим еще одну очень важную особенность операторов && и ||. Если при вычислении операции X && Y первое выражение X окажется нулевым (то есть ложным), то значение второго выражения Y никак не повлияет на результат. Это следует из таблицы истинности операции логическое умножение. Смотрите таблицу истинности этой операции. Поэтому действительно можно игнорировать второе выражение. Аналогично обстоит дело и с оператором ||. Так, если значение первого операнда ненулевое, то значение второго операнда так же не влияет на результат. Потому он так же не вычисляется и игнорируется. Это также следует из таблицы истинности операции логическое сложение. Поэтому нужно учитывать этот факт и не изменять во втором операторе какую-либо переменную, пользуясь операцией ++.
46.Побитовые логические операции языка Си. Операции сдвига
Поразрядное логическое «И» - & (Слева направо)
Поразрядное исключающее «ИЛИ» - ^( Слева направо)
Поразрядное логическое «ИЛИ» - | (слева направо.
Сдвиг влево: <<
Сдвиг вправо: >>
Поразрядные операции состоят из четырех основных операций: отрицание, логическое И, логическое ИЛИ и исключающее ИЛИ.
При выполнении операции поразрядного отрицания все биты, равные 1, устанавливаются равными 0, а все биты равные нулю, устанавливаются равными 1. Для выполнения данной операции в языке С++ используется символ ‘~’
Сдвиг, при котором уходящий бит уходит, не влияя на оставшееся биты, а на место появившегося бита записывается бит 0.
Условный оператор и оператор выбора языка Си.
Инструкция "if" используется для выбора одного из двух направлений дальнейшего продолжения программы. Выбор той или иной последовательности инструкций осуществляется в зависимости от значенияусловия, заключенного в круглые скобки и записанного после оператора if. Поэтому команда "if" часто называется командой условного перехода или командой ветвления. Алгоритмы задач, использующих команды ветвления, называют разветвляющимися. Определение: Алгоритм называется разветвляющимся, если он состоит из нескольких блоков, ветвей млм частей, каждая из которых выполняется в зависимости от выполнения некоторых условий. На этом уроке Вы позакомитесь с основными понятиями и двумя формами оператора условного оператора "if" и далее начнете практические занятия по написанию программ, содержащих условные операторы. Рассмотим теперь две известные формы команды разветвления. 2. Простейшая (укороченная) форма оператора условного перехода if. Простейшая форма оператора if имеет вид: