Двумерные массивы
С позволяет создавать многомерные массивы. Простейшим видом многомерного массива является двумерный массив. Двумерный массив – это массив одномерных массивов. Двумерный массив объявляется следующим образом:
тип имя_массива[размер второго измерения][размер первого измерения];
В следующем примере в двумерный массив заносятся числа от 1 до 12, после этого массив выводится на экран.
#include <stdio.h>
int main()
{
int t, i, num[3][4];
/* загрузка чисел */
for(t=0; t<3; ++t)
for(i=0; i<4; ++i)
num[t][i] = (t*4)+i+1;
/* вывод чисел */
for(t=0; t<3; ++t) {
for(i=0; i<4; ++i)
printf(“%d “, num[t][i]);
printf(“\n”);
}
return 0;
}
В данном примере num[0][0] имеет значение 1, num[0][1] имеет значение 2, num[0][2] имеет значение 3 и так далее. num[2][3] имеет значение 12.
Массивы строк
В программировании типично использование массивов строк. Например, процессор ввода в базу данных может проверять команды пользователя в строковом массиве. Для создания массива строк используется двумерный массив символов. Левый индекс определяет число строк, а правый индекс – максимальное число символов в каждой строке. Данный фрагмент кода объявляет массив из 30 строк, каждая может содержать до 79 символов включительно:
char str_array [30] [80];
Доступ к отдельным строкам очень прост – необходимо написать имя массива только с левым индексом. Например:
gets(str_array[2]);
Данная строка эквивалентна
gets(&str_array[2][0]);
но предыдущий вариант более типичен при написании профессиональных программ.
Рассмотрим программу, использующую массив как основу простейшего текстового редактора.
#include <stdio.h>
#define MAX 100
#define LEN 255
char text[MAX][LEN];
/* простейший текстовый редактор*/
int main()
{
register int t, i, j;
for(t=0; t<MAX; t++) {
printf("%d: ", t);
gets(text[t]);
if(!*text[t]) break;/*выход по пустой строке*/
}
/*посимвольный вывод текста*/
for(i=0; i<t; i++) {
for(j=0; text[i][j]; j++)
printf("%c",text[i][j]);
printf("%c", '\n');
}
getchar();
return 0;
}
Данная программа осуществляет ввод текста, пока не встретится пустая строка. Затем она отображает каждую строку. В целях иллюстрации она выводит текст посимвольно, с использованием правого индекса.
Многомерные массивы
С позволяет создавать массивы с размерностями больше двух. Многомерный массив объявляется следующим образом:
тип имя[размерN]…[размер2][ размер1];
Лекция 6.
План
Индексация с помощью указателей
Размещение массивов
Функции
Оператор return
Выход из функции
Возвращаемые значения
Правила видимости для функций
Аргументы функции
Передача по значению и передача по указателю
Индексация с помощью указателей
Указатели и массивы очень тесно связаны между собой. Имя массива без индекса – это указатель на первый элемент массива. Пусть имеется массив
char p[10];
тогда следующие значения идентичны:
p
&p[0]
Выражение
p == &p[0]
выдаёт истину, поскольку адрес первого элемента и адрес массива совпадают.
Справедливо и обратное. Любой указатель может быть проиндексирован, как будто это массив. Например,
int *p, i[10];
p = i;
p[5] = 1000;
*(p+5) = 1000;
Оба оператора присваивания помещают значение 1000 в шестой элемент i. Первый оператор использует индексацию с р, а второй – арифметику указателей. Результат одинаков.
Данные способы индексации совершенно справедливы для массивов размерности 2 и более. Предположим, что а – это целочисленный массив 10 на 10. Тогда нижеприведенные операторы эквивалентны:
(int *)a
&a[0][0]
К элементу 0, 4 массива а можно обратиться или с помощью индексации массива – a[0][4], или с помощью указателя - *((int *)a+4). Аналогично к элементу 1, 2 можно обратиться или с помощью индексации массива – a[1][2], или с помощью указателя - *((int *)a+12).
Указатели иногда используются для обращения к массивам, поскольку арифметика указателей чаще всего выполняется быстрее, чем индексация массивов. Преимущество наиболее заметно, когда осуществляется последовательный доступ к массиву. В данной ситуации указатель может увеличиваться или уменьшаться с помощью эффективных операторов увеличения или уменьшения. Если же доступ к массиву происходит случайным образом, то лучше использовать индексацию массива, а не указатели.
Двумерные массивы подобны массивам указателей на строки. Поэтому использование отдельных указателей является одним из лёгких способов доступа к элементам двумерного массива.
Следующая функция выводит содержимое указанной строки глобального целочисленного массива num:
int num[10][10];
…
void pr_row(int j)
{
int *p, t;
p = num[j];
for(t=0; t<10; ++t) printf(“%d “, *(p+t));
}
Данный код может быть обобщён, если передавать в качестве аргумента номер строки, длину строки и указатель на первый элемент массива:
void pr_row(int j, int row_dimension, int *p)
{
int t;
p = p + (j * row_dimension);
for(t=0; t< row_dimension; ++t)
printf(“%d “, *(p+t));
}