Материал: Программирование на языке высокого уровня Лекции 09.03.01

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Использование этой группы операторов дает возможность обращения к отдельным битам двоичного представления целочисленных операндов. В С существует 5 бинарных и один унарный побитовый оператор.

& - побитовое И; | - побитовое ИЛИ;

^ - побитовое исключающее ИЛИ; <<, >> - побитовые сдвиги; ~ - побитовое отрицание.

Оператор & выполняет побитовую конъюнкцию своих операндов. a=2;

b=6;

c=a&b;

Оператор | выполнят побитовую дизъюнкцию своих операндов. Его можно, в частности, использовать для проверки числа на четность:

if((a|1)==a)

Оператор ^ устанавливает 1 в том разряде результата, в котором соответствующие разряды операндов имеют различное значение, и О, если в этих разрядах значения совпадают.

a=2;

b=6;

c=a^b;

Операторы << и >> выполняют сдвиг в соответствующем направлении своего левого операнда на число позиций, задаваемое правым операндом, который должен быть положительным. При сдвиге беззнаковых величин освобождающиеся биты заполняются нулями, а при сдвиге вправо знаковой величины результат зависит от реализации.

a=2; d=a--; d=d<<a;

Унарный оператор ~ превращает единичные биты в нулевые и наоборот.

Операторы присваивания.

В выражениях типа a=a+t;, в которых стоящая в левой части присваивания переменная, повторяется и справа, может использоваться видоизмененная форма оператора присваивания: a+=t;.

Таким образом, в С имеется одиннадцать операторов присваивания: =,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=.

Программирование на языке высокого уровня 09.03.01

16

Ввыражениях с использованием видоизмененной формы

оператора

присваивания

вторым

операндом

является

все,

находящееся справа от оператора присваивания:

 

 

a*=b+1; равносильно a=a*(b+1);

 

 

 

 

Условное выражение.

 

 

Если

в программе возникает необходимость

реализовать

выбор

в пределах выражения, и в пределах этого же выражения воспользоваться результатом этого выбора, то можно воспользоваться тернарным оператором ?:. Его синтаксис:

операнд 1 ? операнд 2 : операнд 3 Первым вычисляется операнд 1, который расценивается как

условие. Если результатом вычисления операнда 1 оказалась истина, то вычисляется выражение, являющееся операндом 2, и результат вычисления этого выражения оказывается результатом всего тернарного оператора. В противном случае вычисляется выражение, являющееся операндом 3, и снова его значение является значением всего условного выражения.

a=4;

b=3; c=(a==b?b++:--a);

Условное выражение обычно берется в скобки, так как этот оператор имеет достаточно низкий приоритет (хотя он выше приоритета оператора присваивания)

for(i=1;i<=n;i++)

for(j=1;j<=m;j++) printf(“%d%c”,a[i][j],j!=m?’ ‘:’\n’);

Преобразование типов.

Вслучае, если в одной бинарной операции участвуют операнды разных типов, еще до выполнения операции тип операнда, занимающего меньше места в памяти, приводится к типу другого операнда. Такое неявное приведение типа является временным, только в пределах проводимой операции. Результат будет иметь “старший” тип.

Воперациях присваивания правила другие: значение правой части приводится к типу левой части, который и является типом результата.

Кроме неявного преобразования типов существует и унарный оператор явного преобразования, который называется оператором приведения типа. Его синтаксис:

(тип)выражение; a=(float)sum/n;

Программирование на языке высокого уровня 09.03.01

17

Оператор приведения на самом деле не меняет тип переменной, а временно генерирует значение нового типа.

Таблица приоритетов.

В таблице приоритетов операторы, перечисленные на одной строке, имеют одинаковый приоритет, строки упорядочены по убыванию приоритетов.

Операторы

Выполняются

 

 

() [] -> .

слева направо

 

 

! ~ ++ -- + - * & (тип) sizeof

справа налево

 

 

* / %

слева направо

 

 

+ -

слева направо

 

 

<< >>

слева направо

 

 

< <= > >=

слева направо

 

 

== !=

слева направо

 

 

&

слева направо

 

 

^

слева направо

 

 

|

слева направо

 

 

&&

слева направо

 

 

||

слева направо

 

 

?:

справа налево

 

 

= += -= *= /= %= &= ^= |= <<= >>=

справа налево

 

 

,

слева направо

 

 

Темы 17-20. Массивы и указатели. Обработка текстов и файлов.

Основные свойства массивов.

Массив – это набор данных, элементы которого образуют упорядоченную последовательность, причем все эти элементы должны быть одного типа.

Как и обычные переменные, массивы в С описываются в начале функции или в начале блока, причем при описании массива, как правило, указывается количество ячеек, под которое будет выделяться память.

тип имя[константа 1][константа 2]..[константа n]

Количество размерностей массива стандартом не ограничивается. Если константное выражение в квадратных скобках присутствует, то оно должно быть натуральным числом. Если константное выражение отсутствует, то считается, что описание не завершено. Завершить описание можно двумя способами: либо при другом описании, либо при инициализации массива.

int a[]={5,6,7,8}.

Программирование на языке высокого уровня 09.03.01

18

Память при таком описании выделяется по числу инициализаторов. Счет элементов в массивах начинается с 0. Инициализаторы могут присутствовать и при явно заданном размере массива. Если число инициализаторов меньше размерности массива, то оставшиеся элементы получают значение 0. Если число инициализаторов больше размерности, то выдается сообщение о синтаксической ошибке.

int a[50]={0}; - обнуление массива.

Вмногомерных массивах пустой может быть только первая размерность.

int a[3][3]={3,4,5,6};-массив заполняется по строкам int a[3][3]={{3,4},{5},{6}};

Вмногомерных массивах хранение организовано так, что самый правый индекс в паре или наборе индексов меняется чаще всего.

Хотя память под массив выделяется непрерывным куском, особенности статического распределения памяти приводят к тому, что элементы могут и не храниться связным участком.

Символьные массивы можно инициализировать и без использования фигурных скобок:

char mas[]=”Скоро зачет\n”;

Память будет выделена с учетом символа “\0”. При помощи функции printf символьный массив можно распечатать не используя операторы цикла:

printf(“%s”,mas);

Понятие об указателях.

Указатель – это некоторая переменная, значение которой является адресом другой переменной.

Указатели описываются специальным образом: тип *имя;

float *t; - t будет хранить адреса переменных типа float. Адрес сам по себе является целым числом, память под

указатель выделяется как под целое, но для нормальной работы с указателем необходимо знать тип переменной, адрес которой хранит указатель.

Для извлечения адресов служит унарная операция &, которая называется операцией получения адреса.

t=&b; - t хранит адрес b или указывает на b.

Унарная операция * позволяет извлечь содержимое ячейки, на которую указывает переменная, стоящая после символа *. Эта операция называется операцией доступа по указателю.

k=*t;

t=&b; k=*t; равносильно k=b;

Программирование на языке высокого уровня 09.03.01

19

Связь указателей и массивов.

Любой доступ к элементу массива, осуществляемый с помощью операции индексирования, может быть осуществлён и при помощи указателя.

int a[10]; int *x=&a[0];

х указывает на нулевой элемент массива а, или, иначе говоря, x содержит адрес элемента a[0]. В этом случае адрес любого i-ого элемента массива можно представить как x+i, а его значение – как *(x+i).

Подобные операции верны для любого типа и размера массивов, так как при прибавлении к указателю целого числа i указатель «сдвигается» не на i байтов, а на i элементов этого типа.

x=&a[0]; равносильно

x=a;

Если где-либо на

протяжении программы используется

идентификатор массива без указания индекса, то эта переменная имеет значение, равное адресу нулевого элемента массива.

Существуют и другие способы записи элементов массива и их адресов. Так a[i] можно записать как *(a+i), а запись &a[i]

эквивалентна записи a+i. С другой стороны,

если x – указатель,

то в выражениях его можно использовать с

индексом, то есть

запись x[i] эквивалентна записи *(x+i).

 

Между указателем, которому присвоен адрес нулевого элемента массива, и именем массива существует важное различие. Указатель является переменной, поэтому его значение по ходу программы можно менять (x=a; x++;). Имя массива без указания индекса не может находить в левой части оператора присваивания (записи a++; или a=x; - недопустимы). Это связано с тем, что участок памяти, выделенный под массив, не изменяется на протяжении работы программы.

Над указателями допустимо выполнение следующих операций:

- присвоение указателю в качестве начального значения адреса объекта данных или нуля;

-прибавление к указателю или вычитание из указателя целого числа;

-сравнение двух указателей;

-вычитания одного указателя из другого, если оба указателя указывают на объекты одного типа.

Следующий фрагмент программы можно записать разными способами:

1.int a[5]={3,7,11,8,2}, i, max; max=a[0];

for(i=1;i<=4;i++)

if(a[i]>=max)

max=a[i];

Программирование на языке высокого уровня 09.03.01

20

Источник: https://studfile.net/preview/16415559/