- •1.4.2 Типы и размеры данных в Си
- •1.4.3 Константы
- •1. Целые константы
- •2. Константа действительна
- •3. Символьная константа
- •4. Строчная константа
- •5. Константный выражение
- •Тема 2. Декларации
- •Тема 3. Операторы
- •3.2 Операторы отношений и сравнение на равенство
- •3.5 Операторы присваивания
- •3.5.1 Самый оператор присваивания
- •3.5.2 Другие операторы присваивания Сi
- •3.6 Iнкрементнi и декрементнi операторы
- •Тема 4. Управление
- •4.3 Переключение switch
- •4.4 Цикл While
- •4.5 Цикл for
- •4.6 Операция "," (запятая)
- •4.7 Цикл do - while
- •4.8 Инструкция break
- •4.9 Сontinue
- •4.10 Переходы и метки
- •Тема 5. Указатели и массивы
- •5.1 Указатели
- •5.2 Связь указателей и массивов
- •5.3 Связь между адресной арифметикой и индексированием массивов
- •5.4 Различие между именем массива и указателем (в роли именi массива)
- •5.5 Буквенные указатели
- •5.6 Массивы указателей
- •5.11 Функции проверки свойств символов
- •5.12 Функции преобразования строк
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 = "з_покажчиком"
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 * /