Link: Лекция 12: Массивы и указатели

Последние темы самые интересные. Так что давайте скорее их изучим

Указатели и массивы

Указатель на основной тип:

Переменная р является указателем на символ, т.е. этой переменной должен присваиваться адрес символа.

Указатель на указатель:

Переменная t – указатель на указатель символа.

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

Указатель на функцию:

fуказатель на функцию, возвращающую целое значение.

Массивы

Тип элемента массива может быть :

  • одним из основных типов,
  • типом другого массива,
  • типом указателя pointer ),
  • типом структуры ( struct ),
  • типом объединения ( union ),
  • указателями на функции.

Указатели

Тут нам напоминают про указатели

Тип переменных id1, id2, _idn определяется как тип указателей на тип-данных. Эти переменные служат ссылками на объекты типа тип-данных. Этот тип называется базовым типом переменных-указателей.

Динамические объекты

Раза 3 перечитывал, без пол литра примера не разберешься.

Для создания динамических объектов служат функции malloc и calloc

Создание динамических объектов

Я чувствую как мой мозг плавится. Это тот редкий случай, когда даже пример ничего не объясняет

Я так понял, что malloc и calloc резервируют участок памяти, потом при помощи (int *) мы преобразуем в указатель целого числа и присваиваем pi

Т.е. сейчас pi – указатель на int

Доступ к динамическим объектам

А чтобы присвоить значение динамическому объекту, надо сделать так

Зачем это делается, я не знаю. Но искренне верю, что это очень нужно и никто не сможет меня переубедить в этом.

Вся эта номенклатура “объекты”, “указатели” вообще не идет после изучения ООП

Связь между указателями и массивами

Ограничимся одной фразой

Элемент массива a[i] есть элемент массива, на который указывает значение a+i, т.е. *(a+i), где значение а является адресом первого элемента массива а, а именно a[0]. Все очевидно, если учесть что память заполняется непрерывно (у меня в CLion не так)

Строки – дополнительные сведения о тесной связи между указателями и массивами

Строки – это массивы знаков. По соглашению, последним знаком строки должен быть нулевой знак \0.

Строка может создаваться 2 способами:

После фразы “Нет ничего необычного…” я окончательно утратил связь с реальностью. Поэтому читайте сами.

Инициализация массивов и классы памяти

О, мой мозг возвращается в нормальное состояние

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

Улучшенный вариант:

  1. если мы используем пустые скобки для инициализации массива, то компилятор сам определит количество элементов в списке и выделит для него массив нужного размера.
  2. мы изменили цикл for, так чтобы он сам считал количество элементов (sizeof – определяет размер в байтах объекта/типа), а т.к. в разных системах тоже самый int может быть представлен разным количеством байтов, то мы и делим общий размер массива (состоящий из int) на размер int.

Функции, массивы и указатели

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

Массива years в программе нету. Создается не массив, а указатель на него!

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

Используя указатель в функции convert, мы работаем с массивом, определенном в main

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

  1. Присваивание. Указателю можно присвоить адрес. Обычно мы выполняем это действие, используя имя массива или операцию получения адреса &.
  2. Определение значения. Операция * выдает значение, хранящееся в указанной ячейке.
  3. Получение адреса указателя. Подобно любым переменным, переменная типа указатель имеет адрес и значение. Операция & сообщает нам, где находится сам указатель.
  4. Увеличение указателя. Мы можем выполнять это действие с помощью обычной операции сложения либо с помощью операции увеличения. Увеличивая указатель, мы перемещаем его на следующий элемент массива. (ну вот не работает у меня, хоть стреляйте)
  5. Разность. Можно находить разность двух указателей. Обычно это делается для указателей, ссылающихся на элементы одного и того же массива, чтобы определить, на каком расстоянии друг от друга находятся элементы. Помните, что результат имеет тот же тип, что и переменная, содержащая размер массива!

[toggles class=”yourcustomclass”]
[toggle title=”Как получить адрес переменной?”]использовать операцию &[/toggle]
[toggle title=”Как получить значение, ссылаясь на указатель?”]использовать операцию *[/toggle]
[toggle title=”Могут ли быть элементы массива функциями?”]нет, но элементы массива могут быть указателями на функции[/toggle]
[toggle title=”Что возвращает оператор sizeof?”]размер операнда, в байтах[/toggle]
[toggle title=”Что означает функция malloc?”]Что означает функция malloc?[/toggle]
[/toggles]