
- •Базовые понятия информатики. Понятие «Информатика» и «Информация»
- •Информация
- •Информационные технологии
- •Понятие алгоритма. Свойства и классы алгоритмов. Формы представления алгоритмов
- •Понятие алгоритма. Базовые алгоритмические структуры
- •Представление данных в памяти персонального компьютера.
- •Принципы обработки программных кодов
- •Компиляторы
- •Интерпретатор
- •Язык с. История развития. Основные свойства языка
- •Отличительные особенности языкаC
- •Элементы языка c
- •Константы
- •Базовые типы данных
- •Директива #include
- •Использование void
- •Инструкция return
- •Описание переменных
- •Обработка данных. Операторы
- •Арифметические операторы
- •Приоритет операторов и порядок вычислений
- •Используемые алгоритмы обработки данных
- •Аккумуляторы
- •Преобразования типов данных
- •Декларации и дефиниции функций
- •Формальные и фактические параметры. Вызов функций
- •Возврат функцией значений
- •Переменные в функциях
- •Автоматические (локальные) переменные
- •Внешние (глобальные) переменные
- •Статические переменные
- •Передача параметров по значению
- •Передача параметров по ссылке
- •Значения параметров по умолчанию
- •Перегрузка функций
- •Рекурсия
- •Встроенные функции
- •Обработка символьных данных
- •Функция puts()
- •Функция putchar()
- •Функция printf()
- •Выбор правильных средств вывода информации
- •Функция gets()
- •Функция getchar()
- •Функция scanf()
- •Выбор соответствующих средств ввода данных
- •Управляющие структуры Структуры выбора (if / else)
- •Структуры выбора (switch/case/default)
- •Структуры повторения (циклы)
- •Использование цикла for
- •Использование цикла do...While (постусловие)
- •Использование цикла while (предусловие)
- •Операторы передачи управления Оператор безусловного перехода goto
- •Оператор break
- •Оператор continue
- •Препроцессор языка Си
- •Массивы Объявление переменной массива
- •Использование индексной переменной
- •Инициализация массива при объявлении
- •Передача массивов в функции
- •Использование констант при объявлении массивов
- •Символьные строки
- •Массивы строк
- •Алгоритмы сортировки массива
- •Поиск заданного элемента в массиве
- •Указатели
- •Объявление указателя
- •Указатели на массивы
- •Операции над указателями
- •Указатели на строку
- •Указатели на функцию
- •Функции, возвращающие указатель
- •Указатели на многомерные массивы
- •Массивы указателей
- •Динамическое распределение памяти
- •Структуры данных
- •Реализация одних структур на базе других
- •Очередь
- •Операции над очередями
- •Операции над стеками
- •Ссылочные реализации структур данных
- •Операции над списками
Указатели на массивы
Между указателями и массивами существует тесная связь.
Любую операцию, которую можно выполнить с помощью индексов массива, можно сделать и с помощью указателей. Вариант с указателями обычно оказывается более быстрым, но и несколько более трудным для непосредственного понимания, по крайней мере для начинающего.
Описание int a[10] определяет массив размера 10, т.е. Набор из 10 последовательных объектов, называемых a[0], a[1], ..., a[9]. Запись a[i] соответствует элементу массива через i позиций от начала. Если pa - указатель целого, описанный как
int*pa
то присваивание
pa= &a[0]
приводит к тому, что pa указывает на нулевой элемент массива a; это означает, что pa содержит адрес элемента a[0]. Теперь присваивание
x= *pa
будет копировать содержимое a[0] в x.
Если pa указывает на некоторый определенный элемент массива a, то по определению pa+1 указывает на следующий элемент, и вообще pa-i указывает на элемент, стоящий на i позиций до элемента, указываемого pa, а pa+i на элемент, стоящий на i позиций после. Таким образом, если pa указывает на a[0], то
*(pa+1)
ссылается на содержимое a[1], pa+i - адрес a[i], а *(pa+i) - содержимое a[i].
Эти замечания справедливы независимо от типа переменных в массиве a. Суть определения "добавления 1 к указателю", а также его распространения на всю арифметику указателей, состоит в том, что приращение масштабируется размером памяти, занимаемой объектом, на который указывает указатель. Таким образом, i в pa+i перед прибавлением умножается на размер объектов, на которые указывает pa.
Очевидно существует очень тесное соответствие между индексацией и арифметикой указателей. в действительности компилятор преобразует ссылку на массив в указатель на начало массива. В результате этого имя массива является указательным выражением. Отсюда вытекает несколько весьма полезных следствий. Так как имя массива является синонимом местоположения его нулевого элемента, то присваивание pa=&a[0] можно записать как
pa=a
Таким образом:
Указателем на массив является имя данного массива, а также указатель на его первый элемент. Например:
intarray[10], *аР;
aP=array; // ИлиaP=&array[10]
Для доступа к элементам массива существуют два различных способа.
Доступ к элементам массива может выполняться:
по указателю на массив и индексу элемента, задаваемого в квадратных скобках: первый элемент массива имеет индекс 0;
по указателю на элемент массива.
Для получения адреса элемента массива применяется оператор &.
Имя массива является адресом массива и эквивалентно следующему выражению: &имя_массива[0].
Первый способ связан с использованием обычных индексных выражений в квадратных скобках, например, аггау[3]=1 или array[i+2] = 7. При таком способе доступа записываются два выражения (array и i+2), причем второе заключается в квадратные скобки. Одно из них должно быть указателем, а второе — выражением целого типа. Последовательность записи этих выражений может быть любой, но в квадратных скобках записывается выражение, следующее вторым.
Поэтому записи array [3] и 3[array] эквивалентны и обозначают элемент массива array под номером три.
Указатель, используемый в индексном выражении, не обязательно должен быть константой, указывающей на какой-либо массив, это может быть и переменная.
В частности, после выполнения присваивания аР=аrrау доступ к десятому элементу массива можно получить с помощью указателя аР в форме aP[10] или 10[aP].
Второй способ доступа к элементам массива связан с использованием адресных выражений и операции разадресации в форме (аггау+10)=3 или * (array+i+2) =7.
При таком способе доступа адресное выражение, равное адресу десятого элемента массива, тоже может быть записано разными способами: * (аггау+10) или * (10+array).
При реализации на компьютере первый способ приводится ко второму, т, е. индексное выражение преобразуется к адресному. Для приведенных примеров array[10] и 10[array] преобразуются в
*(аггау+10).
Для доступа к начальному элементу массива (к элементу с нулевым индексом) можно использовать просто значение указателя array или аР. Любая из операций
*аrrау=2;
array[0]=2;
*(аrrау+0)=2;
*аР=2 ;
аР[0]=2;
*(аР+0)=2;
присваивает начальному элементу массива значение 2, но быстрее всего выполнятся операции *аггау=2 и *ар=2, т. к. в них отсутствует сложение.