Материал: Информатика Лекции 27.03.02

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

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

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

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

Операторы

Выполняются

 

 

() [] -> .

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

 

 

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

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

 

 

* / %

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

 

 

+ -

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

 

 

<< >>

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

 

 

< <= > >=

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

 

 

== !=

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

 

 

&

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

 

 

^

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

 

 

|

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

 

 

&&

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

 

 

||

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

 

 

?:

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

 

 

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

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

 

 

,

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

 

 

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

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

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

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

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

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

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

Информатика 27.03.02

51

Память при таком описании выделяется по числу инициализаторов. Счет элементов в массивах начинается с 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;

Информатика 27.03.02

52

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

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

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];

Информатика 27.03.02

53

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

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

if(*(a+i)>=max)

max=*(a+i);

3.int a[]={3,7,11,8,2}, i, *t; int max=*(t=a); for(i=1;i<=4;i++)

if(*(t+i)>=max)

max=*(t+i);

4.int a[]={3,7,11,8,2}, *t; int max=*a; for(t=a;t<=a+4;t++)

if(*t>=max)

max=*t;

При работе с символьными массивами с использованием указателей можно вообще явным образом не выделять память под массив:

char a1,a2;

a1=”Кругом одни враги”; a2=a1+17;

while (--a2>=a1) printf(“%c”,*a2);

printf(“\n”);

Темы 42-43. Классы памяти. Функции. Способы организации взаимодействия между функциями.

Аргументы и возвращаемые значения функций.

В программе на C может быть любое количество функций, среди

них

нет

иерархии. Но

первой будет выполняться функция main(),

где

бы она ни стояла. Любая функция в процессе

своей

работы

может

вызвать любую

другую функцию или даже

саму

себя

(рекурсия).

 

 

 

 

Чтобы вызвать функцию необходимо обратиться к

ней по

имени

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

В результате вызова управление будет передано в вызванную функцию, а затем вернётся к вызывающей функции, когда вызванная функция выполнит все свои инструкции или когда встретится

ключевое слово return.

 

main()

r()

{ r();)

{putchar(‘r’);

Информатика 27.03.02

54

a()

a();

{putchar(‘a’);

putchar(‘r’);

d();

}

putchar(‘a’);

 

}

 

d()

 

{putchar(‘d’);}

 

Заголовок любой функции имеет вид:

 

тип возвращаемого значения ИМЯ (список параметров)

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

Если функция возвращает значение, то её можно вызывать и в качестве оператора, и в качестве операнда. Но, если вызвать её в качестве оператора, то возвращаемое значение будет пропадать

Если функция ничего не возвращает, то её можно вызвать только в качестве оператора. У таких функций в заголовке в качестве типа возвращаемого значения указывается ключевое слово void.

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

формальных параметров в вызываемой функции.

 

 

void main()

 

 

 

 

{int a,b,t;

 

 

 

 

. . .

 

 

 

 

t=power(a,b);

 

 

 

 

. . .

 

 

 

 

}

 

 

 

 

 

int power(int base, int n)

 

 

 

{int a;

 

 

 

 

for(a=1;n>0;--n)

 

 

 

 

 

a=a*base;

 

 

 

 

return a; }

 

 

 

 

Никакие

действия,

которые

происходят

с

формальными

параметрами в вызываемой функции, не могут привести к изменению значений фактических параметров. Это связано с тем, что сами переменные не передаются в вызываемую функцию. Компилятор перед передачей управления делает копии фактических параметров, и именно эти копии попадают в вызываемую функцию. Такой способ передачи аргументов называется передачей по значению. При

передаче по значению обратно в

вызывающую функцию может

Информатика 27.03.02

55