Элементы массива связаны тем

Лекция 3. Массивы

Массив – это совокупность данных, которая обладает следующими свойствами:

  • все элементы массива имеют один и тот же тип;
  • массив имеет одно имя для всех элементов;
  • доступ к конкретному элементу массива осуществляется по индексу (индексам).

Объявление массива имеет следующий синтаксис:
<спецификация типа> <имя> [<константное выражение>]; <спецификация типа> <имя> [ ];

Здесь квадратные скобки являются элементом синтаксиса, а не признаком необязательности конструкции.

Объявление массива может иметь одну из двух синтаксических форм, указанных выше. Квадратные скобки, следующие за именем, – признак того, что переменная является массивом. Константное выражение, заключенное в элементы массива связаны тем квадратные скобки определяет число элементов в массиве. Индексация элементов массива в языке C++ начинается с нуля. Таким образом, последний элемент массива имеет индекс на единицу меньше, чем число элементов массива.

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

Многомерный массив, или массив массивов, объявляется путем задания последовательности константных выражений в квадратных скобках, следующей за именем:
<спецификация типа> <имя> [<константное выражение>][<константное выражение>]... ;

Каждое константное выражение определяет количество элементов в данном измерении массива, поэтому объявление двумерного массива содержит два константных выражение, трехмерного – три и т.д.

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

Примеры объявлений массивов

int x[10];
double y[2][10];

Как и простые переменные, массивы могут быть инициализированы при объявлении. Инициализатор для объектов составных типов (каким является массив) состоит из списка инициализаторов, разделенных запятыми и заключенных в фигурные скобки. Каждый инициализатор в списке представляет собой либо константу соответствующего типа, либо, в свою очередь, список инициализаторов. Эта конструкция используется для инициализации многомерных массивов.

Наличие списка инициализаторов в объявлении массива позволяет не указывать число элементов по его первой размерности. В этом случае количество элементов в списке инициализаторов и определяет число элементов по первой размерности массива. Тем самым определяется размер памяти, необходимой для хранения массива. Число элементов по остальным размерностям массива, кроме первой, указывать обязательно.

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

Примеры инициализации массивов

int a[3] = {0, 1, 2};
double b[5] = {0.1, 0.2, 0.3};
int c[ ] = {1, 2, 4, 8, 16};
int d[2][3] = {{0, 1, 2},
{3, 4, 5}};
int e[3] = {0, 1, 2, 3};

3.1. Доступ к элементу массива

Для доступа к конкретному элементу массива используются так называемые индексные выражения:
<имя массива>[<целочисленное выражение>]

Здесь квадратные скобки являются требованием синтаксисам языка, а не признаком необязательности конструкции.

Индекс массива может быть не только константой, но и выражением, которое имеет целочисленный тип, например, a[i + 1] (здесь a должно быть именем ранее объявленного массива, а i – переменной целого типа).

Объявление массива и индексное выражение, используемое для доступа к элементу массива, имеют схожий синтаксис. Различаются они по месту в программе. Это особенно важно, когда мы определяем индекс последнего элемента массива. Как было сказано ранее, индексы элементов массива в языке C начинаются с 0, и номер последнего элемента на 1 меньше количества элементов массива. Поэтому если Вы объявили массив x из 10 элементов, Вы не можете написать индексное выражение x[10], т.к. в этом случае Вы пытаетесь обратиться к элементу с индексом 10, которого нет в Вашем массиве. Компилятор не выдаст сообщения об ошибке, но результаты работы такой программы будут непредсказуемы.

Имя массива является адресом его начала! Оно имеет тип константный указатель на <тип элементов массива>. Конструкция a[i] эквивалентна (a + i) (см. лекцию 5).

Для многомерного массива надо указать соответствующее количество индексов в квадратных скобках.

3.2. Обработка массивов

Для обработки элементов массива обычно используется оператор пошагового цикла for.

for (int i = 0;
i < n;
i++)
<тело цикла>

Для обработки многомерного массива используется соответствующее количество циклов.

Массивы не самодостаточны в том смысле, что не гарантируется хранение информации о количестве элементов вместе с самим массивом. В большинстве реализаций С++ отсутствует проверка диапазона индексов для массивов. Таков традиционный низкоуровневый подход к массивам. Более совершенное понятие массива можно реализовать при помощи классов.

В С++ массивы тесно связаны с указателями. Имя массива можно использовать в качестве указателя на его первый элемент. Гарантируется осмысленность значения указателя на элемент, следующий за последним элементом массива. Это важно для многих алгоритмов. Но ввиду того, что такой указатель на самом деле не указывает ни на какой элемент массива, его нельзя использовать ни для чтения, ни для записи. Результат получения адреса элемента массива, предшествующего первому, не определён, и такой операции следует избегать.

Неявное преобразование имени массива в указатель на его первый элемент широко используется в вызовах функций.

int f(..., int x[],...) {... } int f(..., int x,...) {... } void main() { int a[10];...
f(..., a,...);... }

Неявное преобразование массива в указатель при вызове функции приводит к потере информации о размере массива. Вызываемая функция должна каким-либо образом определить этот размер, чтобы выполнять осмысленные действия.

При объявлении многомерного массива как параметра функции можно опустить только первую размерность.

int g(..., int x[][10],...) {... }

Это ограничение при желании можно обойти. Правда, при этом возникают другие проблемы (см. пример 3 в конце лекции).

3.3. Ввод/вывод массивов

В языке C нет возможности вводить и выводить весь массив одним оператором ввода/вывода. Можно вводить и выводить только один элемент массива. Следовательно, для того чтобы ввести весь массив, надо использовать цикл.

const int nmax массива = 10;
int a[nmax], n; printf("Введите количество элементов массива (от 1 до %d): "), nmax;
scanf("%d", &n);
if (n < 1 || n > nmax) { printf("Количество элементов массива должно быть от 1 до %d!\n", nmax); return; }
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);

Вывод также осуществляется в цикле.

for (int i = 0; i < n; i++) printf("a[%d] = %3d\n", i + 1, a[i]);

В результате на экране мы увидим примерно следующий текст: a[1] = 4 a[2] = 15 a[3] = -2...

3.4. Пример 1. Обработка одномерного массива

Даны три массива разной размерности. Определить в каком массиве больше сумма элементов.

#include <cstdio> #include <locale.h> const int nmax = 100;
int ArrayInput(int n, double x[], char fname);
double Sum(double x[], int n); void main(int argc, char argv[]) { double a[nmax], b[nmax], c[nmax]; double sa, sb, sc, max; int na, nb, nc; setlocale(LC_ALL, "rus");
if (argc < 4) { printf("Недостаточно параметров!\n"); return; } if (!ArrayInput(&na, a, argv[1])) return; if (!ArrayInput(&nb, b, argv[2])) return; if (!ArrayInput(&nc, c, argv[3])) return; sa = Sum(a, na); sb = Sum(b, nb); sc = Sum(c, nc); max = sa; if (sb > max) max = sb; if (sc > max) max = sc; if (sa == max) printf("Массив А имеет максимальную сумму элементов: %9.3lf\n", max); if (sb == max) printf("Массив B имеет максимальную сумму элементов: %9.3lf\n", max); if (sc == max) printf("Массив C имеет максимальную сумму элементов: %9.3lf\n", max); } double Sum(double x[], int n) { double s = 0; for (int i = 0; i < n; i++) s += x[i]; return s; } int ArrayInput(int n, double x[], char fname) { FILE file; if ((file = fopen(fname, "r")) == NULL) { printf("Невозможно открыть файл '%s'\n", fname); return 0; } if (fscanf(file, "%d", n) < 1) { printf ("Ошибка чтения из файла '%s'\n", fname); fclose(file); return 0; } if (n < 0 || n > nmax) { printf("Кол-во эл-тов массива должно быть от 1 до %d! (файл '%s')\n", nmax, fname); return 0; } for (int i = 0; i < n; i++) if (fscanf(file, "%lf", &x[i]) < 1) { printf ("Ошибка чтения из файла '%s'\n", fname); fclose(file); return 0; } fclose(file); return 1; }

3.5. Пример 2. Обработка двумерного массива

Для каждой строки матрицы проверить наличие нулевых элементов.

Первый способ

#include <cstdio> #include <locale.h> const int nmax = 100;
void Zeros(double x[][nmax], int m, int n, int z[]);
void main(int argc, char argv[]) { double a[nmax][nmax]; int m, n, z[nmax]; FILE file; setlocale(LC_ALL, "rus"); if (argc < 2) { printf("Недостаточно параметров!\n"); return; } if ((file = fopen(argv[1], "r")) == NULL) { printf("Невозможно открыть файл '%s'\n", argv[1]); return; } if (fscanf(file, "%d%d", &m, &n) < 2) { printf ("Ошибка чтения из файла '%s'\n", argv[1]); fclose(file); return; } if (m < 0 || m > nmax || n < 0 || n > nmax) { printf("Количество строк и столбцов матрицы должны быть от 1 до %d!\n", nmax); return; } for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) if (fscanf(file, "%lf", &a[i][j]) < 1) { printf ("Ошибка чтения из файла '%s'\n", argv[1]); fclose(file); return 0; } fclose(file); Zeros(a, m, n, z); for (int i = 0; i < m; i++) if (z[i]) printf("В %3d строке есть нулевые элементы\n", i + 1); } void Zeros(double x[][nmax], int m, int n, int z[]) { int i, j; for (i = 0; i < m; i++) for(z[i] = 0, j = 0; j < n; j++) if (x[i][j] == 0) { z[i] = 1; break; } }

Второй способ

#include <cstdio> #include <locale.h> const int nmax = 100;
int Zeros(double x[], int n); void main(int argc, char argv[]) { double a[nmax][nmax]; int m, n;
...
for (int i = 0; i < m; i++) if (Zeros(a[i], n))
printf("В %3d строке есть нулевые элементы\n", i + 1); } int Zeros(double x[], int n) { for (int j = 0; j < n; j++) if (x[j] == 0) return 1; return 0; }

3.6. Пример 3. Суммирование элементов матрицы

Даны две матрицы разного размера. Функция Sum находит сумму элементов матрицы, не зависимо от того, что матрицы имеют разное количество столбцов. Обратите внимание, что функция будет выдавать корректный результат, только если используются все объявленные элементы матриц.

#include <cstdio> #include <locale.h> double Sum(double x, int m, int n); void main(int argc, char argv[]) { const int na = 4, mb = 3, nb = 5; double a[na][na], b[mb][nb]; double sa, sb; FILE file; setlocale(LC_ALL, "rus"); if (argc < 3) { printf("Недостаточно параметров!\n"); return; } if ((file = fopen(argv[1], "r")) == NULL) { printf("Невозможно открыть файл '%s'\n", argv[1]); return; } for (int i = 0; i < na; i++) for (int j = 0; j < na; j++) if (fscanf(file, "%lf", &a[i][j]) < 1) { printf ("Ошибка чтения из файла '%s'\n", argv[1]); fclose(file); return; } fclose(file); if ((file = fopen(argv[2], "r")) == NULL) { printf("Невозможно открыть файл '%s'\n", argv[2]); return; } for (int i = 0; i < mb; i++) for (int j = 0; j < nb; j++) if (fscanf(file, "%lf", &b[i][j]) < 1) { printf ("Ошибка чтения из файла '%s'\n", argv[2]); fclose(file); return; } fclose(file);
sa = Sum(a[0], na, na);
sb = Sum(reinterpret_cast<double >(b), mb, nb);
printf("SumA = %6.2lf\nSumB = %6.2lf\n", sa, sb); } double Sum(double x, int m, int n) { double s = 0; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) s += x[i n + j]; return s; }

Содержание Правильный CSS!


Закрыть ... [X]

Урок по теме "Одномерные массивы " Номер максимального элемента Платье связанное крючком мотивами схемы и



Элементы массива связаны тем Применение указателей при работе с массивами
Элементы массива связаны тем Элементы массива Ссылки, связанные с данной
Элементы массива связаны тем Массивы 3.6. Пример 3. Суммирование элементов матрицы
Элементы массива связаны тем Глава 5. Указатели и массивы
Элементы массива связаны тем 5. Заполнение массива, элементы которого связаны некоторой закономерностью
МАССИВЫ Понятие и элементы массива Userator сервис для заработка в интернете в социальных сетях «Маг Хобби» магазин товаров для творчества Выкройка юбки-карандаш с рельефами и застежкой на пуговицы Вязаный меланжевый пуловер спицами от 0 до 3 - Портал рукоделия и моды Жакеты и кардиганы крючком (схемы и описания)