Рассмотрим инициализацию указателей типа char:

char *ptr = "hello, world";

Переменная *ptr является указателем, а не массивом. Поэтому строковая константа "hello, world" не может храниться в нем. Тогда возникает вопрос, где она хранится. Для этого следует знать, что происходит, когда компилятор встречает строковую константу. Он создает так называемую таблицу строк, где сохраняет строковые константы, которые попадаются ему по ходу чтения текста программы [4]. Следовательно, когда встречается объявление с инициализацией, то компилятор сохраняет "hello, world" в таблице строк, а указатель *ptr записывает ее адрес.

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

Массив указателей фиксированных размеров вводится одним из следующих определений:

тип *имя_массива [размер];

тип *имя_массива [ ] = инициализатор;

тип *имя_массива [размер] = инициализатор;

В данной инструкции тип может быть как одним из базовых типов, так и производным; имя_массива – идентификатор, определяемый пользователем по правилам языка С; размер – константное выражение, вычисляемое в процессе трансляции программы; инициализатор – список в фигурных скобках значений элементов заданного типа (т. е. тип).

Рассмотрим примеры:

int data[7]; // обычный массив

int *pd[7]; // массив указателей

int *pi[ ] = { &data[0], &data[4], &data[2] };

Здесь каждый элемент массивов pd и pi является указателем на объекты типа int. Значением каждого элемента указателей pd[j] и pi[k] может быть адрес объекта типа int. Все 7 элементов указателя pd не инициализированы. В массиве указателя pi три элемента, и они инициализированы адресами конкретных элементов массива data.

НЕ нашли? Не то? Что вы ищете?

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

Приведем пример массива строк о студенте, задаваемого с помощью массива указателей:

char *ptr[ ] = {

"Surname", //фамилия

"Name", // имя

"group", // группа

"ACOUY" // специальность

};

С помощью массива указателей можно инициализировать строки различной длины. Каждый элемент массива ptr[] указывает на одномерный массив символов (строку) независимо от других указателей.

В языке программирования С предусматриваются ситуации, когда указатели указывают на указатели. Такие случаи называются многоуровневой адресацией. Пример объявления указателя на указатель:

int **ptr2;

В приведенном объявлении **ptr2 – это указатель на указатель на число типа int. Наличие двух звездочек свидетельствует о том, что имеется двухуровневая адресация. Для получения значения конкретного числа следует выполнить следующие действия:

int x = 88, *ptr, **ptr2;

ptr = &x;

ptr2 = &ptr;

printf("%d", **ptr2);

В результате в выходной поток (на экран пользователя) будет выведено число 88. В приведенном фрагменте переменная *ptr объявлена как указатель на целое число, а **ptr2 – как указатель на указатель на целое. Значение, выводимое в выходной поток (число 88), получается в результате операции разыменования указателя **ptr2.

В многомерных массивах указатели содержат адреса элементов массива построчно. Рассмотрим пример двухмерного целочисленного массива М размера 3 × 5, т. е. состоящего из 3 строк и 5 столбцов, и определим указатель:

int M[3][5]= {{1,2,3,4,5},{–6,–7,–8,–9,–10},{11,12,13,14,15}};

int *ptr;

Элементы массива (по индексам) располагаются в ячейках памяти по строкам в следующем порядке:

M[0][0], M[0][1], M[0][2], M[0][3], M[0][4], M[1][0], M[1][1], M[1][2], M[1][3], M[1][4], M[2][0], M[2][1], M[2][2], M[2][3], M[2][4].

Сначала запоминается первая строка, затем – вторая, потом – третья. В данном случае двухмерный массив – это массив трех одномерных массивов, состоящих из 5 элементов.

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

ptr == &M[0][0]; // 1-я строка, 1-й столбец

ptr + 1 == &M[0][1]; // 1-я строка, 2-й столбец

ptr + 2 == &M[0][2]; // 1-я строка, 3-й столбец

ptr + 3 == &M[0][3]; // 1-я строка, 4-й столбец

ptr + 4 == &M[0][4]; // 1-я строка, 5-й столбец

ptr + 5 == &M[1][0]; // 2-я строка, 1-й столбец

ptr + 6 == &M[1][1]; // 2-я строка, 2-й столбец

ptr + 7 == &M[1][2]; // 2-я строка, 3-й столбец

ptr + 8 == &M[1][3]; // 2-я строка, 4-й столбец

ptr + 9 == &M[1][4]; // 2-я строка, 5-й столбец

ptr + 10 == &M[2][0]; // 3-я строка, 1-й столбец

ptr + 11 == &M[2][1]; // 3-я строка, 2-й столбец

ptr + 12 == &M[2][2]; // 3-я строка, 3-й столбец

ptr + 13 == &M[2][3]; // 3-я строка, 4-й столбец

ptr + 14 == &M[2][4]; // 3-я строка, 5-й столбец

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

ptr = &M[0][0];

*(ptr + i*n + j);

где i – номер строки заданной матрицы, j – номер столбца, n – число столбцов в матрице.

Пример 6. Написать программу считывания строк разной длины с использованием арифметики указателей.

Программный код решения примера:

#include <stdio. h>

#include <conio. h>

int main (void) {

int i, n;

char *ptr[ ] = {"one", "two", "three", "four", "five",\

"six", "seven", "eight", "nine", "ten"};

n = sizeof(ptr)/sizeof(ptr[0]);

printf("\n\t Strings of various length:\n");

for (i = 0; i < n; ++i)

printf("\n%12d) %s", i+1, ptr[i]);

printf("\n\n Press any key: ");

_getch();

return 0;

}

В программе использован одномерный массив указателей. Функция printf() и спецификатор преобразования %s допускают применение в качестве параметра указателя на строку. При этом на дисплей выводится не значение указателя, а содержимое адресуемой им строки. Обратный слэш \ служит для переноса содержимого операторной строки на новую строку. Оператор sizeof() вычисляется во время компиляции программы, превращаясь обычно в целую константу, значение которой равно размеру типа или объекта, в данном случае соответствует размеру массива указателей.

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


Результат выполнения программы показан на рис. 6.1.

Рис. 6.1. Пример считывания строк различной длины

7.  Динамическое распределение памяти в языке С

Динамическая память – это оперативная память компьютера, предоставляемая программе при ее работе. Динамическое размещение данных означает использование этой памяти при работе программы. Статическое размещение (например, явное определение массива переменных заданного типа) осуществляется компилятором в процессе компиляции (запуска) программы.

Указатели используются для динамического выделения памяти компьютера при хранении данных. Динамическое распределение означает, что программа готовит память во время выполнения.

Память, выделяемая в С функциями динамического распределения данных, находится в так называемой динамически распределяемой области памяти (англ. heap – «куча»). Динамически распределяемая область памяти – это свободная область памяти, не используемая программой, операционной системой или другими программами. Ее размер заранее неизвестен, но, как правило, в ней достаточно места для размещения данных программы. Хотя размер динамически распределяемой области памяти очень большой, все же она конечна и может быть исчерпана.

Основу системы динамического распределения памяти в С составляют библиотечные функции calloc(), malloc(), realloc() и free().

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

Основные порталы (построено редакторами)

Домашний очаг

ДомДачаСадоводствоДетиАктивность ребенкаИгрыКрасотаЖенщины(Беременность)СемьяХобби
Здоровье: • АнатомияБолезниВредные привычкиДиагностикаНародная медицинаПервая помощьПитаниеФармацевтика
История: СССРИстория РоссииРоссийская Империя
Окружающий мир: Животный мирДомашние животныеНасекомыеРастенияПриродаКатаклизмыКосмосКлиматСтихийные бедствия

Справочная информация

ДокументыЗаконыИзвещенияУтверждения документовДоговораЗапросы предложенийТехнические заданияПланы развитияДокументоведениеАналитикаМероприятияКонкурсыИтогиАдминистрации городовПриказыКонтрактыВыполнение работПротоколы рассмотрения заявокАукционыПроектыПротоколыБюджетные организации
МуниципалитетыРайоныОбразованияПрограммы
Отчеты: • по упоминаниямДокументная базаЦенные бумаги
Положения: • Финансовые документы
Постановления: • Рубрикатор по темамФинансыгорода Российской Федерациирегионыпо точным датам
Регламенты
Термины: • Научная терминологияФинансоваяЭкономическая
Время: • Даты2015 год2016 год
Документы в финансовой сферев инвестиционнойФинансовые документы - программы

Техника

АвиацияАвтоВычислительная техникаОборудование(Электрооборудование)РадиоТехнологии(Аудио-видео)(Компьютеры)

Общество

БезопасностьГражданские права и свободыИскусство(Музыка)Культура(Этика)Мировые именаПолитика(Геополитика)(Идеологические конфликты)ВластьЗаговоры и переворотыГражданская позицияМиграцияРелигии и верования(Конфессии)ХристианствоМифологияРазвлеченияМасс МедиаСпорт (Боевые искусства)ТранспортТуризм
Войны и конфликты: АрмияВоенная техникаЗвания и награды

Образование и наука

Наука: Контрольные работыНаучно-технический прогрессПедагогикаРабочие программыФакультетыМетодические рекомендацииШколаПрофессиональное образованиеМотивация учащихся
Предметы: БиологияГеографияГеологияИсторияЛитератураЛитературные жанрыЛитературные героиМатематикаМедицинаМузыкаПравоЖилищное правоЗемельное правоУголовное правоКодексыПсихология (Логика) • Русский языкСоциологияФизикаФилологияФилософияХимияЮриспруденция

Мир

Регионы: АзияАмерикаАфрикаЕвропаПрибалтикаЕвропейская политикаОкеанияГорода мира
Россия: • МоскваКавказ
Регионы РоссииПрограммы регионовЭкономика

Бизнес и финансы

Бизнес: • БанкиБогатство и благосостояниеКоррупция(Преступность)МаркетингМенеджментИнвестицииЦенные бумаги: • УправлениеОткрытые акционерные обществаПроектыДокументыЦенные бумаги - контрольЦенные бумаги - оценкиОблигацииДолгиВалютаНедвижимость(Аренда)ПрофессииРаботаТорговляУслугиФинансыСтрахованиеБюджетФинансовые услугиКредитыКомпанииГосударственные предприятияЭкономикаМакроэкономикаМикроэкономикаНалогиАудит
Промышленность: • МеталлургияНефтьСельское хозяйствоЭнергетика
СтроительствоАрхитектураИнтерьерПолы и перекрытияПроцесс строительстваСтроительные материалыТеплоизоляцияЭкстерьерОрганизация и управление производством