Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базовий курс языка C.doc
Скачиваний:
1
Добавлен:
10.11.2018
Размер:
307.2 Кб
Скачать

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

[ ] = * Оператор [] в Си эквивалентный работе оператора * (компилятор превращает [] в *).

i-й элемент: а [i]

с указателями:

int * pa;

pa = & a [0]

x = * pa; / * x = a [0] (= -1) * /

Адресная арифметика

Если ра указывает на некоторый элемент, то ра +1 указывает на следующий элемент , pа + i - на i-й элемент после ра , ра-1 - на предыдущей (перед ра) .

Во всех языках программирования команда вырезки элемента из массива ([]) стоит десятки машинных команд, а в языке Си - ни одной лишней команды.

! Если pa = & a [0]

то * (pa + 1) ~ a [1]

pa + i ~ адрес [i]

* (Pa + i) ~ a [i]

Пример 3:

int * pa;

int a [5] = {-1, -10, -100, -1000, -10000};

int a1, a2;

pa = & a [0]; / * pa =- 1 * /

a1 = * (pa +1); / * a1 = a [1] * /

a2 = * (pa +2); / * a2 = a [2] * /

5.3 Связь между адресной арифметикой и индексированием массивов

Значение переменной или выражения типа массив есть адрес нулевого элемента.

Пример 4:

int a [5], * pa, * pm

pa = & a [0]; pm = a; / * эквивалентны записи * /

Поэтому эквивалентны следующие выражения:

a [i] * (a + i)

& A [i] a + i

pa [i] * (pa + i)

Указатели по обычные переменные можно объединять в массив.

5.4 Различие между именем массива и указателем (в роли именi массива)

Указатель - переменная, поэтому допустимо использовать указатели в выражениях со сменными. 

Допустим:

int * pa; int a [5]

pa = a; / * -> на a [0] * /

pa + +; / * -> на a [1] * /

Недопустимо:

int * pa;

int a [5];

a = pa;

а + +;

- Изменять начальный адрес массива невозможно.  - Имя массива не является переменной.

В Си нет операций над массивами в целом.

5.5 Буквенные указатели

В Си нет строчного типа данных.  Строчная константа - это массив букв (символов).

Количество байтов: количество букв +1 (для символа \ 0 (конец строки)).

Пример 5:

char * pstr;

pstr = "с указателем";

- Строка не копируется, а копируется указатель на этот массив

Так же строка может быть промоделирован как буквенный указатель.  Различия между декларациями строк как массива и с помощью указателя

Пример 6:

char s_str [] = "як_масив"

char * p_str = "з_покажчиком"

Прямоугольник 10

s_str: - элементы s_str могут меняться;  - но s_str всегда ссылается на то же место в памяти; р_str: - при изменении указателя он будет ссылаться на другое р_str = "изменили";

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

Недопустимо:

s_str = "изменили";

Все функции для работы со строками в размещенные в бiблiтечному файле .

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

Дано текст, в котором фраза "номер рисунка" находится над рисунком, а название рисунка - под ним.  Превратить тест, чтобы "номер рисунка" находился под ним, а название - над рисунком. 1) Выбираем способ подачи текста  Строки текста - переменной длины , следовательно, нельзя текст представить следующим образом: V [N] [M] (!) -> Використуемо массив указателей на тип данных char :

Пример 7:

# Define KL 100

int n1, n2; / * номера строки * /

char * V [KL]; / * текст * /

char * temp; / * временная переменная * /

int k; / * рабочая переменная * /

temp = V [n1];

V [n1] = V [n2];

V [n2] = temp;

k = KL; / * печать текста * /

while (k -> 0)

printf ("% S \ n", * V + +);

 

5.7 Инициализация массивов указателей

Пример 8:

/ * Массив наименований месяцев года * /

char * m_name [] = {"ошибка", "январь", "февраль", "март", "апрель",

"Май", "июнь", "июль", "август", "сентябрь",

"Октябрь", "ноябрь", "декабрь"};

/ * Обращение по номеру месяца * /

(N <1 | | n> 12)? m_name [0]: m _name [n];

 

5.8 Многомерные массивы

Пример 9:

/ * Массив праздничных дней * /

int mpr [2] [7] =

= {{1, 7, 8, 1, 2, 9, 26, 24}, / * дни * /

{1, 1, 3, 5, 5, 5, 6, 8} / * месяца * /

};

/ * Обращение к элементам: * /

......

d_may1 = mpr [0] [3];

m_may1 = mpr [1] [3];

5.9 Указатели вместо многомерных массивов

Пример 10:

/ * 2 способа подачи двомiрних массивов * /

1) char a [3] [4];

2) char * b [3];

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

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

5.10 Функции обработки строк

Библиотека языка Си для работы со строками ( string.h )

strlen | strcat | strcpy | strcmp

strlen (S), S-строка (определяет длину строки) - количество информационных символов (без \ 0)

Пример 11:

int l;

l = strlen ("пример"); / * l = 6 * /

strcat (S1, S2) / * S1 + = S2 (конкатенация) * /  В строку S1 конкатенуеться копия строки S2, результат возвращается через имя функции. S1-зминютьеся, S2-не меняется.

Пример 12:

char a [30] = "Белеет", / * a = "Белеет" * /

b [] = "парус"; / * b = "парус" * /

strcat (a, b); / * a = "Белеет парус" * /

/ * B = "парус" * /

strcpy (S1, S2) / * S1 <= S2 (S1 = S2) * /  Строка S2 копiюеться в строку S2.

Пример 13:

char a [30] = "Белеет", / * a = "Белеет" * /

b [] = "парус"; / * b = "парус" * /

char * c;

strcpy (c, a); / * c = "Белеет" * /

strcat (c, b); / * c = "Белеет парус" * /

strcmp (S1, S2) / * Сравнение строк в лексiко-графическом порядке * / strcmp (S1, S2) = 0, если S1 = S2 strcmp (S1, S2) <> 0, иначе:

  • > 0, если S1> ​​S2

  • <0, если S1 <S2

  • = 0, если S1 = S2

Пример 14:

int r1, r2, r3;

char a [] = "ПС-08А", / * a = "ПС-08А" * /

b [] = "ПС-08б"; / * b = "ПС-08б" * /

char * c;

r1 = strcmp (a, c); / * r1 = 0 * /

r2 = strcmp (a, b); / * r1 <0 * /

r3 = strcmp (b, c); / * r1> 0 * /