Массивы и указатели
Автор работы: Пользователь скрыл имя, 20 Марта 2011 в 00:49, лекция
Описание работы
Между массивами и указателями существует очень тесная связь, поэтому обычно их рассматривают вместе. Но, прежде чем исследовать эту связь, давайте проверим наши знания о массивах и пополним их, а уж после этого перейдем к изучению связи между массивами и указателями.
Содержание работы
Массивы
Инициализация массивов и классы памяти
Указатели массивов
Функции, массивы и указатели
Использование указателей при работе с массивами
Операции с указателями
Многомерные массивы
Инициализация двумерного массива
Указатели и многомерные массивы
Функции и многомерные массивы
Файлы: 1 файл
13_Массивы и указатели.doc
— 183.50 Кб (Скачать файл) Сначала
запоминается первая строка, за ней вторая,
затем третья и т. д. Таким образом, в нашем
примере:
pri == &zippo[0][0] /* 1-я строка, 1 столбец */
pri + 1 == &zippo[0][1] /* 1-я строка, 2 столбец */
pri + 2 == &zippo[1][0] /* 2-я строка, 1 столбец */
pri
+ 3 == &zippo[1][1] /* 2-я строка, 2 столбец */
Получилось?
Хорошо, а на что указывает pri + 5? Правильно,
на
zippo[2][1].
Мы описали двумерный массив как массив массивов. Если zippo является именем нашего двумерного массива, то каковы имена четырех строк, каждая из которых является массивом из двух элементов? Имя первой строки zippo [0], имя четвертой строки zippo [3]; вы можете заполнить пропущенные имена. Однако имя массива является также указателем на этот массив в том смысле, что оно ссылается на первый его элемент. Значит,
zippo[0] == &zippo[0][0]
zippo[1] == &zippo[1][0]
zippo[2] == &zippo[2][0]
zippo[3]
== &zippo[3][0]
Это
свойство является более, чем новшеством.
Оно позволяет использовать функцию,
предназначенную для
/* одномерная функция, двумерный массив */
main ()
{
static int junk [3] [4] = {
int row;
for (row = 0; row < 3; row++ )
printf(" Среднее строки %d равно %d.\n",
row, mean(junk[row], 4) ); /* junk [row] — одномерный массив из четырех элементов */
}
/* находит среднее в одномерном массиве */
int mean(array,n)
int array[], n;
{
int index; long sum;
if (n > 0)
{
for (index = 0, sum = 0; index < n; index++)
sum += (long) array [index];
return( (int) (sum/n) );
}
else
{
printf("Heт массива\n");
return(0);
}
}
Результат
работы программы:
Среднее строки 0 равно 5.
Среднее строки 1 равно 250.
Среднее
строки 2 равно 50.
- Функции и многомерные массивы
Предположим,
что вы хотите иметь функцию, работающую
с двумерным массивом, причем со
всем целиком, а не с частями. Как
вы запишите определения функции и ее
описания? Подойдем к этому более конкретно
и скажем, что нам нужна функция, управляющая
массивом junk[][] в нашем последнем примере.
Пусть функция main () выглядит так:
/* junk в main */
main ()
{
static int junk[3][4] = {
stuff(junk);
}
Функция stuff () использует в качестве аргумента junk, являющийся указателем на весь массив. Как написать заголовок функции, не зная, что делает stuff ()?
Попробуем
написать:
stuff (junk)
int
junk[];?
или
stuff(junk)
int
junk[][];?
Нет и нет. Первые два оператора еще будут работать некоторым образом, но они рассматривают junk как одномерный массив, состоящий из 12 элементов. Информация о расчленении массива на строки отсутствует.
Вторая
попытка ошибочна, потому что хотя
оператор и указывает, что junk является
двумерным массивом, но нигде не говорится,
из чего он состоит. Из шести строк и двух
столбцов? Из двух строк и шести столбцов?
Или из чего-нибудь еще? Компилятору недостаточно
этой информации. Ее дают следующие операторы:
stuff(junk)
int
junk[][4];
Они сообщают компилятору, что массив следует разбить на строки по четыре столбца.
Массивы
символьных строк являются особым случаем,
так как у них нулевой символ
в каждой строке сообщает компилятору
о конце строки. Это разрешает описания,
подобные следующему:
char
*list[];
Символьные строки представляют одно из наиболее частых применений массивов и указателей; мы вернемся к этой теме позднее.
Что вы должны были узнать
- Как объявить одномерный массив: long id_ no [200];
- Как объявить двумерный массив: short chess[8] [8];
- Какие массивы можно инициализировать: внешние и статические.
- Как инициализировать массив: static int hats[3] = {10,20,15};
- Другой способ инициализации: static int caps[] = {3,56,2};
- Как получить адрес переменной: использовать операцию &
- Как получить значение, ссылаясь на указатель: использовать операцию *
- Смысл имени массива: hats == &hats[0]
- Соответствие массива и указателя: если ptr = hats; то ptr + 2 == &hat[2]; и *(ptr + 2) == hat[2];
- Пять операций, которые можно применять для переменных типа указатель: см. текст.
- Метод указателей для функций, работающих с массивами.
Вопросы и ответы
Вопросы
- Что напечатается в результате работы этой программы?
#define PC(X, Y) printf("%c %c\n", X, Y)
char ref[] = { D, О, L, Т};
main ()
{
char *ptr;
int index;
for (index = 0; ptr = ref; index < 4; index++, ptr++ )
PC(ref[index], *ptr);
}
- Почему в вопросе 1 массив ref описан до оператора main ()?
- Определите значение *ptr и *(ptr + 2) в каждом случае:
int *ptr;
static int boop[4] = {12, 21, 121, 212};
ptr = boop;
- float *ptr;
static float awk[2][2] = { { 1.0, 2.0}, {3.0, 4.0}};
ptr = awk[0];
- int *ptr;
static int jirb[4] = {10023, 7};
ptr = jirb;
- int = *ptr;
static int torf[2][2) = {12, 14, 16};
ptr = torf[0];
- int *ptr;
static int fort[2][2] = {{ 12}, {14, 16}};
ptr = fort[0];
- Предположим, у нас есть описание static int grid[30][100];
- Выразите адрес grid [22] [56] иначе.
- Выразите адрес grid[22] [0] двумя способами.
- Выразите адрес grid[0][0] тремя способами.
Ответы
D D
О О
L L
Т Т
- По умолчанию такое положение ref относит его к классу памяти типа extern, a массивы этого класса памяти можно инициализировать.
- 12 и 121
- 1.0 и 3.0
- 10023 и 0 (автоматическая инициализация нулем)
- 12 и 16
- 12 и 14 (именно 12 появляется в первой строке из-за скобок).
- &grid[22][56]
- &grid[22][0] и grid[22]
- &grid[][] и grld[0] и grid
Упражнение
- Модифицируйте нашу метеорологическую программу таким образом, чтобы она выполняла вычисления, используя указатели вместо индексов. (Вы по-прежнему должны объявить и инициализировать массив.)