Спонсоры сайта:

Наличие этой страницы в поиске?

Информеры ТИЦ и PR

  Yandex ТИЦ:  
   Google PR:  

Путешественникам, меломанам, бизнесменам, вебмастерам, новости.

Содержание | <<< | >>>

Двухмерные массивы





Стандартом С определены многомерные массивы. Простейшая форма многомерного массива — двухмерный массив. Двухмерный массив — это массив одномерных массивов. Объявление двухмерного массива d с размерами 10 на 20 выглядит следующим образом:

int d[10][20];

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

Аналогично обращению к элементу одномерного массива, обращение к элементу с индексами 1 и 2 двухмерного массива d выглядит так:

d[1][2]

В следующем примере элементам двухмерного массива присваиваются числа от 1 до 12 и значения элементов выводятся на экран построчно:

#include <stdio.h>

int main(void)
{
  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("%3d ", num[t][i]);
    printf("\n");
  }

  return 0;
}

В этом примере num[0][0] имеет значение 1, num[0][1] — значение 2, num[0][2] — значение 3 и так далее. Наглядно двухмерный массив num можно представить так:

num[t][i]
      | 0  1  2  3
    --+----------- 
    0 | 1  2  3  4
    2 | 5  6  7  8
    3 | 9  10 11 12

Двухмерные массивы размещаются в матрице, состоящей из строк и столбцов. Первый индекс указывает номер строки, а второй — номер столбца. Это значит, что когда к элементам массива обращаются в том порядке, в котором они размещены в памяти, правый индекс изменяется быстрее, чем левый. На рис. 4.2 показано графическое представление двухмерного массива в памяти.

Рис. 4.2. Двухмерные массивы

            Объявление массива char ch[3][4]

        Правый индекс определяет номер столбца
                   |          |          |
   о               V          V          V
   п      +----------+----------+----------+
Л  р    ->|ch [0] [0]|ch [0] [1]|ch [0] [2]|
е  е      +----------+----------+----------+
в  д
ы  е      +----------+----------+----------+
й  л  с ->|ch [1] [0]|ch [1] [1]|ch [1] [2]|
   я  т   +----------+----------+----------+
и  е  р
н  т  о   +----------+----------+----------+
д     к ->|ch [2] [0]|ch [2] [1]|ch [2] [2]|
е  н  и   +----------+----------+----------+
к  о
с  м      +----------+----------+----------+
   е    ->|ch [3] [0]|ch [3] [1]|ch [3] [2]|
   р      +----------+----------+----------+

Объем памяти в байтах, занимаемый двухмерным массивом, вычисляется по следующей формуле:

количество_байтов =
= размер_1-го_измерения × размер_2-го_измерения × sizeof(базовый_тип)

Например, двухмерный массив 4-байтовых целых чисел размерностью 10×5 занимает участок памяти объемом

10×5×4

то есть 200 байтов.

Если двухмерный массив используется в качестве аргумента функции, то в нее передается только указатель на начальный элемент массива. В соответствующем параметре функции, получающем двухмерный массив, обязательно должен быть указан размер правого измерения[1], который равен длине строки массива. Размер левого измерения указывать не обязательно. Размер правого измерения необходим компилятору для того, чтобы внутри функции правильно вычислить адрес элемента массива, так как для этого компилятор должен знать длину строки массива. Например, функция, получающая двухмерный массив целых размерностью 10×10, должна быть объявлена так:

void func1(int x[][10])
{
  /* ... */
}

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

x[2][4]

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

/* Простая база данных оценок студентов. */
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

#define CLASSES  3
#define GRADES  30

int grade[CLASSES][GRADES];

void enter_grades(void);
int get_grade(int num);
void disp_grades(int g[][GRADES]);

int main(void)
{
  char ch, str[80];

  for(;;) {
    do {
      printf("(В)вод оценок студентов\n");
      printf("В(ы)вод оценок студентов\n");
      printf("Вы(х)од\n");
      gets(str);
      ch = toupper(*str);
    } while(ch!='В' && ch!='ы' && ch!='х');

    switch(ch) {
      case 'В':
        enter_grades();
        break;
      case 'ы':
        disp_grades(grade);
        break;
      case 'х':
        exit(0);
    }
  }

  return 0;
} 

/* Занесение оценок студентов в массив. */
void enter_grades(void)
{
  int t, i;

  for(t=0; t<CLASSES; t++) {
    printf("Класс № %d:\n", t+1);
    for(i=0; i<GRADES; ++i)
      grade[t][i] = get_grade(i);
  }
}

/* Ввод оценок. */
int get_grade(int num)
{
  char s[80];

  printf("Введите оценку студента № %d:\n", num+1);
  gets(s);
  return(atoi(s));
}

/* Вывод оценок. */
void disp_grades(int g[][GRADES])
{
  int t, i;

  for(t=0; t<CLASSES; ++t) {
    printf("Класс № %d:\n", t+1);
    for(i=0; i<GRADES; ++i)
      printf("Студент № %d имеет оценку %d\n", i+1, g[t][i]);
  }
}

Массивы строк

В программах на языке С часто используются массивы строк. Например, сервер базы данных сверяет команды пользователей с массивом допустимых команд. В качестве массива строк в языке С служит двухмерный символьный массив. Размер левого измерения определяет количество строк, а правого — максимальную длину каждой строки. Например, в следующем операторе объявлен массив из 30 строк с максимальной длиной 79 символов:

char str_array[30][80];

Чтобы обратиться к отдельной строке массива, нужно указать только левый индекс. Например, вызов функции gets() с третьей строкой массива str_array в качестве аргумента можно записать так:

gets(str_array[2]);

Этот оператор эквивалентен следующему:

gets(&str_array[2][0]);

Из этих двух форм записи предпочтительной является первая.

Для лучшего понимания свойств массива строк рассмотрим следующую короткую программу, в которой на основе применения массива строк создан простой текстовый редактор:

/* Очень простой текстовый редактор. */
#include <stdio.h>

#define MAX 100
#define LEN 80

char text[MAX][LEN];

int main(void)
{
  register int t, i, j;

  printf("Для выхода введите пустую строку.\n");

  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++) putchar(text[i][j]);
    putchar('\n');
  }

  return 0;
}

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

----------

[1]Размер правого измерения указывать не нужно, если в вызывающей функции массив объявлен как **х и размещен динамически (см. главу 5)


Содержание | <<< | >>>

C++ исходники. Все примеры - рабочие:

часы:

Dev C++ WinAPI Стрелочные часы Analog Clock

Dev C++ WinAPI Цифровые прозрачные часы. Текст на рабочем столе. Digital transparent clock. Text on desktop

Dev C++ OLE WinApi CALENDAR and DIGITAL CLOCK (15kb). Календарь и цифровые часы

Dev C++ OLE WinAPI Календарь и цифровые часы почти Vista SideBar всего 21kb

плееры:

Microsoft Visual C++ 2008 Direct Show DVD Mini Player 10.5kb

Dev C++ WinAPI Микро медиа плеер 3.5kb

Dev C++ WinAPI Мини медиа плеер 4.5kb

Dev C++ WinAPI Hint Всплывающая подсказка

Dev C++ WinAPI RECT - имитатор кнопки

Dev C++ WinAPI Заполнить ListBox

Dev C++ WinAPI Заполнить, редактировать, сохранить, загрузить ListBox (PlayList)

Dev C++ WinAPI Индикатор уровня

Dev C++ WinAPI MP3 Микро плеер Открыть с помощью...

Dev C++ WinAPI Своя кнопка

изображения:

Dev C++ GDI+ WinAPI Mini FotoResizer (16kb), изменяет размеры всех фото (JPG) до указанного размера в выбраной папке и её подпапках

Dev C++ WinAPI Сохранить BITMAP экрана, десктопа, окна, клиентской области.

Dev C++ WinAPI Изменить размер изображения BMP RESIZE. Загрузка изображений из ФАЙЛА, вывод на экран и сохранение в файл.

Dev C++ WinAPI Загрузка изображений из РЕСУРСОВ и вывод на экран.

Dev C++ GDI+ WinAPI. Преобразовать изображения из одного формата в другой (JPG в BMP, GIF, PNG и обратно ), используя дополнительные библиотеки GDI+. Загрузка изображений из файла и сохранение в файл.

Dev C++ GDI+ WinAPI масштабирование JPG RESIZE

Dev C++ OLE WinAPI. Преобразовать изображения из JPG в BMP, используя дополнительные библиотеки OLE. Загрузка изображений из РЕСУРСОВ и сохранение в файл.

Dev C++ OLE WinAPI преобразовать JPG в BMP, используя дополнительные библиотеки OLE. Загрузка изображений из ФАЙЛА и сохранение в файл.

Dev C++ OLE WinAPI масштабирование BMP RESIZE

разное:

Dev C++ WinAPI Dev C++ Преобразовать цвет точки экрана в HTML код

Dev C++ WinAPI NOTIFYICONDATA WS_EX_TOOLWINDOW Иконка в области уведомлений (notification area, tray, трей). Удалить с панели задач (taskbar).

Dev C++ WinAPI ShellExecute Создать ссылку на WEB сайт

Dev C++ WinAPI ShellExecute Создать окно со ссылкой на WEB сайт

Dev C++ WinAPI CreateProcess ShellExecute WinExec Запуск приложения из приложения

Dev C++ OLE WinAPI Создать регион Regions PopUp Меню Menu

Dev C++ FindFiles. Поиск файлов заданного типа (в примере *.JPG) в папке и её подпапках

библиотеки:

Скачать библиотеку GDI+ для Dev C++

Скачать справочнник с примерами языка C.