Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Массивы и указатели на языке Си
Массивы описывают регулярную структуру данных одного типа. Одномерные массивы: int temp [365]; char arr [10]; char *point[10]; Двумерные массивы: int array[4] [10]; char arr [3] [7]; Число в [ ] указывает количество элементов массива, поэтому: temp [365] – массив из 365 элементов. Доступ к каждому элементу осуществляется по его индексу (номеру), т.е. temp[0], temp[1], …, temp[364]- последний элемент. Элементы массива нумеруются начиная с 0. Можно также использовать многомерные массивы, например: int arr [k] [l] …[n]; Однако следует помнить, что для хранения элементов таких массивов требуется значительный объем памяти. Рассмотрим, как происходит размещение элементов массива в памяти ЭВМ. Как правило, элементы массива занимают последовательные ячейки памяти. При этом элементы размещаются таким образом, что самый последний индекс возрастает быстрее. Это в случае двумерного массива означает, что он будет записываться построчно: строка за строкой. Поскольку указатели указывают адрес ячейки, то между массивами и указателями существует тесная связь. Вспомним, что имя массива – это указатель на его первый элемент. По существу массив можно рассматривать как индексированный указатель. Доступ к элементам массива осуществляется по номеру индекса. При этом приращение индекса на единицу вызывает перемещение указателя на число байт, соответствующее объекту данного типа: для целых чисел на 2 байта, для действительных - на 4 байта и т.д. Объявления int mas[] и int *mas идентичны по действию: оба объявляют mas указателем. Индекс массива действует аналогично стрелки часов, показывающей по очереди на каждый следующий элемент массива. Пример 4.5: int mas[10]; int *ptr; ptr = mas; // присваивает адрес указателю // следующие операции дадут один и тот же результат: mas[2] = 20; *(ptr + 2) = 20; // следующая операция прибавит 2 к первому элементу: *ptr + 2;
Указатели и многомерные массивы. Рассмотрим двумерный массив и действия с указателями. int mas[4][2]; int *ptr; ptr = mas; ptr сейчас указывает на первый столбец первой строки, т.е. ptr = = mas = = & mas [0] [0]; Увеличим указатель: ptr+1 = = & mas [0] [1]; ptr+2 = = & mas [1] [0]; ptr+3 = = & mas [1] [1] и т.д. Двумерный массив можно представить как массив массивов. В нашем случае мы имеем четырех элементный массив, состоящий из двух элементов. Примечательно, что этот четырех элементный массив можно представить в виде одномерного mas[0], …, mas[3]. При этом имя массива по-прежнему является указателем на его первый элемент, т.е. mas[0]= =& mas[0] [0]. На что же будут указывать mas[i]? В этом случае mas [i] указывает на i-тую строку, т.е. на первый элемент i - й строки. Таким образом mas [0] == & mas [0] [0]; mas [1] == & mas [1] [0]; mas[2] == & mas [2] [0]; mas[3] == & mas [3] [0]; Массивы и указатели – различия. Имя массива – является указателем – константой. Описания: 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 [ ] = “Груша”. Отличие заключается в том, что во втором случае будет выделено ровно столько памяти, сколько необходимо. Массивы и указатели символьных строк Часто бывает необходимо иметь массив символьных строк. При этом возможно задать два типа описаний: 1) 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
|