Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты по проге.docx
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
630.61 Кб
Скачать

Инициализация массивов

Общая форма инициализации массива аналогична инициализации переменной:

тип имя_массива[размер1]...[размер№] = {список_значений};

Пример для одномерного массива В следующем примере массив целых из 10 элементов инициализируется числами от 1 до 10:

int i[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Здесь элементу i[0] присваивается 1, a i[9] — 10.

Так же можно задать массив переменной длины с помощью функции: void f(int dim)

{

char str[dim]; /* символьный массив переменной длины */

/* ... */

} Здесь размер массива str определяется значением переменной dim, которая передается в функцию f() как параметр. Таким образом, при каждом вызове f() создается массив str разной длины.

Операции над указателями

Оператор & — это унарный оператор, возвращающий адрес своего операнда. Например, оператор m = &count; присваивает переменной m адрес переменной count. Адрес — это номер первого байта участка памяти, в котором хранится переменная. Адрес и значение переменной — это совершенно разные понятия. Оператор & можно представить себе как оператор, возвращающий адрес объекта. Оператор * — это унарный оператор, возвращающий значение переменной, расположенной по указанному адресу. Например, если m содержит адрес переменной count, то оператор

q = *m;

присваивает переменной q значение переменной count. Замечание: *(&count)=count и &(*m)=m Присваивание указателей int x = 99; |

int *p1, *p2; |

| оба указателя (p1 и р2) ссылаются на х.

p1 = &x; |

p2 = p1; |

Унарные операции ++ и – Е сли указатель связан с типом char, то при выполнении операций ++ -- его числовое значение изменяется на 1. Если int – на 2, float и long – на 4. Т.о., при изменении указателя на 1, указатель переходит «к началу» следующего или предыдущего поля той длины, которая определяется типом.

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

Замечание! 2 указателя нельзя суммировать, но можно прибавлять константу. Сравнивать допустимо только с указателями того же типа или с null

Связь между массивами и указателями Указатели и массивы тесно связаны друг с другом. В языке С существуют два метода обращения к элементу массива: адресная арифметика и индексация массива. Стандартная запись массивов с индексами наглядна и удобна в использовании, однако с помощью адресной арифметики иногда удается сократить время доступа к элементам массива. Имя массива без индекса — это указатель на первый элемент массива. Рассмотрим, например, следующий массив:

char p[10];

Следующие два выражения идентичны:

p

&p[0]

Выражение p == &p[0] принимает значение ИСТИНА, потому что адрес 1-го элемента массива — это то же самое, что и адрес массива.

Как уже указывалось, имя массива без индекса представляет собой указатель. И наоборот, указатель можно индексировать как массив. Рассмотрим следующий фрагмент программы:

int *p, i[10];

p = i;

p[5] = 100; /* в присваивании используется индекс */

*(p+5) = 100; /* в присвоении используется адресная арифметика */

Оба оператора присваивания заносят число 100 в 6-й элемент массива i. Первый из них индексирует указатель p, во втором применяются правила адресной арифметики. В обоих случаях получается один и тот же результат.

Можно также индексировать указатели на многомерные массивы. Например, если а — это указатель на двухмерный массив целых размерностью 10×10, то следующие два выражения эквивалентны:

а &a[0][0] Более того, к элементу (0,4) можно обратиться двумя способами: либо указав индексы массива: а[0][4], либо с помощью указателя: *((int*)а+4). Аналогично для элемента (1,2): а[1][2] или *((int*)а+12). В общем виде для двухмерного массива справедлива следующая формула:

a[j][k] эквивалентно *((базовый_тип*)а+(j*длина_строки)+k)

Массив указателей

Как и объекты любых других типов, указатели могут быть собраны в массив. В следующем операторе объявлен массив из 10 указателей на объекты типа int:

int *x[10];

Для присвоения, например, адреса переменной var третьему элементу массива указателей, необходимо написать:

x[2] = &var;

В результате этой операции, выражение *x[2] принимает то же значение, что и var.

Для передачи массива указателей в функцию используется тот же метод, что и для любого другого массива: имя массива без индекса записывается как формальный параметр функции. Например, следующая функция может принять массив x в качестве аргумента:

void display_array(int *q[])

{

int t;

for(t=0; t<10; t++)

printf("%d ", *q[t]);

}

Необходимо помнить, что q — это не указатель на целые, а указатель на массив указателей на целые. Поэтому параметр q нужно объявить как массив указателей на целые. Нельзя объявить q просто как указатель на целые, потому что он представляет собой указатель на указатель.

Массивы указателей часто используются при работе со строками. Например, можно написать функцию, выводящую нужную строку с сообщением об ошибке по индексу num:

void syntax_error(int num)

{

static char *err[] = {

"Нельзя открыть файл\n",

"Ошибка при чтении\n",

"Ошибка при записи\n",

"Некачественный носитель\n"

};

printf("%s", err[num]);

}

Массив err содержит указатели на строки с сообщениями об ошибках. Здесь строковые константы в выражении инициализации создают указатели на строки. Аргументом функции printf() служит один из указателей массива err, который в соответствии с индексом num указывает на нужную строку с сообщением об ошибке. Например, если в функцию syntax_error() передается num со значением 2, то выводится сообщение «Ошибка при записи».

Билет 6. Метод барьера.

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