Массивы и указатели – различия.
Имя массива – является указателем – константой. Описания:
char string_1[20]= «Язык Си» и
char *string_2 = «Язык Си»;
размещают в памяти соответствующую строку символов. Различие состоит в том, что указатель string_1 является константой, а указатель string_2 – переменной. Это различие проявляется в случае использования операции единичного приращения ++. Эту операцию можно применять только к переменным. Поэтому string_2++ - допустимая конструкция, а string_1++ - запрещенная. Однако и в том и в другом случае можно использовать операции сложения с указателем, т.е.
string_1 + i ;
string_2 + i ; - допустимые конструкции.
При задании массива символов можно указывать размер явно, например:
char mas_1 [10] = “Яблоко”;
Или определить массив по умолчанию
Char mas_2 [ ] = “Груша”.
Отличие заключается в том, что во втором случае будет выделено ровно столько памяти, сколько необходимо.
Массивы указателей
Размер одного массива данных не более 64 Кб. Но в реальных задачах могут использоваться массивы, требующие ОП больше. Например, массив данных типа floatиз 300 строк и 200 столбцов потребует 300*200*4 = 240000 Кб.
Для решения поставленной задачи можно использовать массив указателей и динамическое выделение ОП для каждой строки матрицы. Строка матрицы не должна превышать 64 Кб.
Итак, массивы могут содержать указатели. Типичным использованием такой структуры данных является формирование массива строк. Каждый элемент такого массива - строка, но в C++ строка является, по существу, указателем на ее первый . Таким образом, каждый элемент в массиве строк в действительности является указателем на первый символ строки. Рассмотрим объявление массива suit, который может быть полезным для представления колоды карт.
char *suit[4] = { "Черви", "Бубны", "Трефы", "Пики" };
Элемент объявления suit[4] указывает массив из 4 элементов. Элемент объявления char * указывает, что тип каждого элемента массива suit — «указатель наchar». Четыре значения, размещаемые в массиве— это «Черви», «Бубны», «Трефы», «Пики». Каждое из них хранится в памяти как строка, завершающаяся нулевым символом, которая на один символ длиннее, чем число символов текста, указанного в кавычках. Эти четыре строки имеют длину 6, 6, 6 и 5 символов, соответственно. Хотя это выглядит так, словно эти строки помещены в массив suit, на самом деле в массиве хранятся лишь указатели (Рис.). Каждый из них указывает на первый символ соответствующей ему строки. Таким образом, хотя размер массива suit фиксирован, он обеспечивает доступ к строкам символов любой длины. Эта гибкость — один из примеров мощных возможностей структурирования данных в С++.
Строки символов могли бы быть размещены в двумерном массиве, в котором каждая строка представляет одну масть, а каждый столбец представляет одну из букв имени масти. Такая структура данных должна иметь фиксированное количество столбцов на строку и это количество должно быть таким большим, как самая длинная строка. Поэтому затраты памяти на хранение большого количества строке, большинство из которых короче, чем самая длинная строка, будут значительными.
-
suit[0]
‘ч’
‘e’
‘р’
‘в’
‘и’
‘\0’
suit[1]
‘б’
‘у’
‘б’
‘н’
‘ы’
‘\0’
suit[2]
‘т’
‘р’
‘е’
‘ф’
‘ы’
‘\0’
suit[3]
‘п’
‘и’
‘к’
‘и’
‘\0’
Рис. Графическое представление массива suit
Пример :
int mas[10];
int *ptr;
ptr = mas; // присваивает адрес указателю
// следующие операции дадут один и тот же результат:
mas[2] = 20;
*(ptr + 2) = 20;
// следующая операция прибавит 2 к первому элементу:
*ptr + 2;
Массивы и указатели символьных строк
Часто бывает необходимо иметь массив символьных строк. При этом возможно задать два типа описаний:
char string_1[10][20]; //10 строк по 20 символов
2) char* string_2[10]; // массив из 10 указателей на строки символов. Какие здесь различия? Различие заключается в том, что в первом случае задается “прямоугольный” массив, в котором каждая строка имеет фиксированную длину, а во втором определяется “рваный” массив, где длина каждой строки занимает столько байт , сколько необходимо.
Например:
char string_1[3] [7] ={“Яблоко”, “Слива” , “Груша”};
char *string_[3]={“яблоко”, “слива”, “груша”};
Заполнение массивов будет следующим:
string_1: string_2:
Яблоко\0 яблоко\0
Слива\0\0 слива\0
Груша\0\0 груша\0