Всоответствии со старым стилем функция состоит из трех составных
частей:
∙Заголовок.
∙Определение формальных параметров.
∙Тело функции.
Заголовок функции, написанной в соответствии со старым стилем, имеет
следующий формат:
[тип ] имя([список_формальных_параметров ])
В отличие от нового стиля организации функций в старом стиле в заголовке функции в аргументных скобках не указывались типы формальных параметров. Кроме того, в старом стиле записи определений функции указывать тип возвращаемого значения указывать было не обязательно. При этом отсутствии спецификации типа по умолчанию предполагался тип int. Стандарт С99 отменил действие принципа умолчания в отношении типа int. Например, заголовок функции max2(), написанный в соответствии со старым стилем, имел бы следующий вид:
double max2(a, b)
Определения формальных параметров записывались вне заголовка функции и располагались после заголовка функции, но до ее тела.
Тело функции, записанной в соответствии со старым стилем, строится по тем же правилам, что и использовании нового стиля. Для иллюстрации организации функций в соответствии со старым стилем перепишем
определение функции max2(), приведенное выше.
/* Определение функции max2(), записанное в соответствии со
старым стилем*/ |
// Заголовок функции |
|
double |
max2(a, b) |
|
double |
a, b; |
// Объявление формальных параметров |
{ |
|
// Начало тела функции |
double max; if(a > b)
elsemax = a;
max = b; return max;
}
Массивом называется упорядоченная совокупность однотипных величин, объединенных одним именем. Упорядоченность хранящихся в массиве данных достигается путем использования системы индексов. Количество индексов определяет размерность массива. Различают одномерные массивы и многомерные массивы. При работе с элементами одномерных массивов используется один индекс, а при работе с многомерными массивами – два и более индексов.
86
Назначение массивов состоит в хранении некоторой совокупности данных для их последующей обработки.. Приведем примеры ситуаций, когда возникает необходимость в использовании массивов.
∙Одна и та же совокупность однородных данных неоднократно используется в процессе обработки.
∙Для отделения ввода данных от их обработки.
∙Для сохранения однородной совокупности исходных данных с
целью облегчения конечному пользователю анализа результатов вычислений.
Выше подчеркивалось, что целесообразность в использовании массива однородных данных. Это предполагает, что все элементы этой совокупности будут обрабатываться одинаково. Например, это характерно для обработки данных полученных в процессе табулирования некоторой математической функции. С другой стороны, объединять в массив элементы комплексного числа вряд ли целесообразно. Это обусловлено тем обстоятельством, что действительная и мнимая часть комплексного числа должна обрабатываться по-разному. В языке Си каждый массив располагается в непрерывной области памяти. Первый его элемент располагается по наименьшему адресу, а последний - по самому большему. В языке Си нумерация по любому из измерений массива начинается с нуля.
Следует отметить, что в языке Си имеется тесная связь между массивами и указателями. Наиболее ярким проявлением этой связи является то обстоятельство, что имя массива является константным указателем на его первый элемент.
При определении (объявлении) и при обращении к отдельным элементам массива используется бинарный оператор индексирования ([...]). Вначале будут рассмотрены, которые предусмотрены стандартом языка С89. Особенность этих массивов состоит в том, что размер памяти, которая должна быть для них выделена, должен быть известен на этапе компиляции. Затем в пункте 1.39. будут рассмотрены массивы с переменными размерами. Особенностью последнего вида массивов является то положение, что определение необходимего объем памяти может быть отложено до этапа выполнения программы.
При работе с переменными, являющимися массивами, следует различать его объявление и определение. Здесь имеет место полная аналогия с обычными переменными. Определение массива позволяет компьютеру выделить память. Определение массива должно содержать информацию, достаточную для выделения памяти. Каждый массив должен иметь только одно определение. На количество объявлений массива ограничений нет. Отличительным признаком объявления является наличие в нем зарезервированного слова extern.
87
Определение одномерного массива отличается от определения простой переменной наличием после определяемого имени квадратных скобок, в которых записывается константное выражение целого типа, определяющее количество элементов массива. Определение может быть дополнено набором инциализаторов, который заключается в фигурные скобки.
Общий формат определения одномерного массива в стиле стандарта С89 имеет следующий:
<α> <β>[<γ>] = <μ>;
Здесь α- тип элементов, хранящихся в массиве; β - имя массива, [..] – оператор индексирования; γ – константное выражение, определяющее размер памяти, выделяемой для хранения элементов массива Конструкция «= <μ>» используется для инициализации массива; μ – список инициализаторов.
Обращает на себя внимание использование в объявлении и в определении массива оператора индексные скобки
Для обращения к отдельным элементам одномерного массива имеет сдующий формат:
<β>[<σ>]
Здесь β - имя массива, [] – оператор индексные скобки, σ- арифметическое целочисенное выражение, значение которого определяет индекс элемента.
Пример 1 Определение глобального и локального массива.
#define MSIZE1 20 int x[MSIZE]; int main(void)
{
double z[5]; z[0] = 10;
}
В этом примере имеются опредеделения двух одномерных массивов. Первый массив (x) является глобальным. Он предназначен для хранения 20 элементов типа. int. В связи с тем, что определение этого массива находится вне функций, его элементы в момент выделения памяти будут обнулены. Второй массив (z) является локальным. Он предназначен для хранения 5 элементов типа. double. Элементы этого массива будут содержать «мусор». В теле функции main() с помощью оператора присваивания элементу массива z с нулевым индексом присваивается значение 10.
Пример 2. Определение и объявление массивов.
Пусть в некоторой программе имеются два модуля. В первом модуле содержится функция main(), а во втором модуле c с именем module содержатся объявление и опрелеление массива x.
88
// Первый модуль #inclde “module.h” int main(void)
{
// Работаем с массивом x x = 10;
}
//Второй модуль (module). Интерфейсный файл module.h #define MSIZE 20
extern x[]; // Это объявление массива x
//Второй модуль. Файл реализации module.c
#include “module1.c”
int x[MSIZE];// Здесь выделяется память для массива x
В интерфейсном файле module.h содержится объявление массива x. а в файле реализации module.c находится определение массива x. Функция полчает доступ к этому массиву, что позволяет ей записать в элемент x[0] значение 10.
Пример 3. Инициализация массива во время определения
Рассмотрим программный код, приведенный ниже.
#define MSIZE 5 int main(void)
{
int x1[MSIZE] = {1, 3, 5, 7, 9};
int x2[MSIZE] = {1, |
3, 5}; |
|
|
int x3[MSIZE] = {1, |
3, 5, 7, 9, 11};// Ошибка |
||
int x4[] = |
{1, 3, 5, |
7, 9}; |
|
int x5[MSIZE] = {0};
}
В рассматриваемом коде объявлено пять массивов. Все массивы имеют одинаковый размер, определяемый константой MSIZE, равной 5. Здесть количество элементов в массиве совпадает с количеством инициализаторов. При объявлении массива x1 список инициализации содержит 5 констант. Элемент x1[0] этого массива инциализируется первой константой, равной 1, затем элемент x1[1] инициализируется константой 2 и т. д. Наконец, элемент x1[4] инициализируется последней константой из списка инициализации, равной 9. Количество элементов массива и количество инциализаторов может не совпадать. Если количество элементов массива превышает количество инициализаторов, то элементы массива, для которых «не хватило» инициализаторов обнуляются. Например, x2[3] == x2[4] == 0; Случай, когда инициализаторов превышает количество элементов массива, рассматривается как ошибочный. При компиляции определения массива x3 будет выдано сообщение об ошибке. Заметим, что при наличии списка инициализации размер требуемой памяти можно не указывать, что, и сделано при определении массива x4.
89
Общий формат определения одномерного массива в стиле стандарта С89 имеет следующий:
<α> <β>[<γ1>][<γ2>] = <μ>;
Здесь α- тип элементов, хранящихся в массиве; β - имя массива, [..] – оператор индексирования; γ1 – константное выражение, определяющее количество строк в двумерном массиве, а γ2 - константное выражение, определяющее количество столбцов в двумерном массиве. Конструкция «= <μ>» используется для инициализации массива; μ – список инициализаторов.
Приведем пример определения двумерного массива.
#define MROW 2 #define MCOL 3
int main(void)
{
double m[MROW][MCOL] = {
{1, 3, 5}, {2, 4, 6}
};
}
В этом примере содержится определение двумерного массива m, в котором может храниться не более 2 строк и не более трех столбцов. Элементы массива инициализированы во время его определения. Первая строка массива содержит числа 1, 3 и 5, а вторая строка - 2, 4 и 6. Элементы массива имеют тип double.
Все операции с элементами массива выполняются поэлементно. Приведем два примера.
Пример 1. Копирование одномерных массивов.
Постановка задачи. Даны два массива одинаковых размеров x1 и x2. Скопировать часть n элементов массива x1 в массив x2.
Решение. Организуем арифметический цикл, рассчитанный на n повторений. Поэлементно будем копировать элементы массива x1 в массив x2. Программный код, представленный ниже, решает рассматриваемую
задачу.
#define MSIZE 20 #include <stdio.h> int main(void)
{
int x1[MSIZE] = {1, 3, 5}; int x2[MSIZE];
int n; printf(“n=”); scanf(“%d”, &n);
for(int i = 0; i < n; i++) x2[i] = x1[i];
//..
90