Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab_C-08.doc
Скачиваний:
2
Добавлен:
21.11.2019
Размер:
81.92 Кб
Скачать

Другой способ описания типа для аргумента-массива

Чтобы повысить самодокументируемость программ (сделать очевидным, что по смыслу программы аргумент функции принимает массив) в Си предлагается второй способ описания аргументов-массивов:

void f(int a[]); (1)

Однако нужно понимать, что на самом деле это только более удобный для восприятия синтаксис и различия с void f(int *a); чисто внешние. Компилятор, встретив определение аргумента в виде int a[], заменит его на int *a.

По-прежнему при передаче в функцию будет утерян размер фактического массива.

Замечание

Не будет синтаксической ошибкой, если в квадратных скобках указать размер массива — void f(int a[12]). Однако с практической точки зрения для одномерного массива это бесполезно, так как размер учитываться никак не будет.

ЗАДАНИЕ 2 (передача одномерного массива)

1. В функции main определяется и инициализируется массив из нескольких чисел типа double.

Написать функцию total, которой передается массив чисел типа double, Функция суммирует элементы этого массива и возвращает полученную сумму.

Внутри функции размер массива вычислить нельзя. Поэтому при вызове функции total передается не только массив, но и количество элементов в нем.

Чтобы сделать программу более универсальной и не привязывать ее к конкретному размеру, количество элементов массива вычисляется в функции main: с помощью операции sizeof следующим образом: получаем размер памяти, занятой массивом, и делим результат на размер типа double. Затем найденное значение подставляется в вызов функции total.

Вывести на экран:

а) вычисленное количество элементов в массиве,

б) значение полученной суммы чисел.

2. Чтобы убедиться, что компилятор две синтаксические формы определения типа формального параметра воспринимает как одну, использовать в прототипе и определении функции разные способы задания аргумента.

Передача в функцию двумерного массива

Почти все рассуждения, которые относятся к передаче одномерного массива в функцию, остаются справедливыми и для двумерных массивов. Исключение составляет тип данных формального параметра, соответствующего массиву.

Замечание

Для двумерных массивов (т.е. матриц) важнейшей характеристикой является количество элементов в строке (или столбцов матрицы). Действительно, 20 чисел можно представить в виде двумерного массива многими способами: 20*1, 2*10, 4*5, 10*2 и т.д. Так как элементы массивов перебираются по строкам (например, при инициализации), то задание количества элементов в строке однозначно определит структуру массива.

В Си имя массива — это указатель на тип элемента массива. Двумерный массив — это одномерный массив строк матрицы (тоже одномерных массивов). Поэтому имя двумерного массива — это указатель на строку матрицы, т.е. на массив из конкретного числа элементов.

Пример

В функцию f нужно передать единственный аргумент — двумерный массив arr2 чисел типа int. Размеры массива: 6 строк и 8 столбцов.

Тогда прототип функции должен будет выглядеть следующим образом (с точностью до имени формального параметра):

void f(int (*a)[8]); (2)

Замечания

1. Если при передаче одномерного массива конкретные размеры массива указывать было не нужно, то для двумерного массива обязательно должно быть указано количество столбцов (второй размер, в примере это 8).

Конструкция (*a)[8] читается, как "указатель на массив из 8 элементов" (запись *a[8] означает "массив из 8 указателей", что не соответствует условию примера).

2. Двумерный массив — это одномерный массив строк матрицы. Поэтому в функции информация о количестве его элементов (строк переданного ей двумерного массива) теряется.

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

void f(int a[][8]);

Такая форма описания аргумента более проста и понятна. Но вновь это опять только внешнее представление, потому что компилятор перед трансляцией программы преобразует его к виду (2).

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

ЗАДАНИЕ 3 (передача в функцию двумерного массива)

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

1. Функция main.

1.1. В функции main определен двумерный числовой массив arr2[][3] со значениями типа int. Массив инициализирован так, чтобы в нем было 4 полных строки (т.е. размеры 4*3).

1.2. С помощью sizeof определяется размер объекта arr2. Используя этот размер и известное количество столбцов (их 3), подсчитать количество строк в массиве. Вывести на экран оба результата.

1.3. Выполнить вызов функции total2, передав ей

а) массив arr2,

б) количество строк в массиве.

2. Функция total2.

В функции total2 выполняются следующие действия.

2.1. С помощью sizeof определяется размер объекта, соответствующего формальному параметру-массиву, и этот размер выводится на экран.

Сравнить эту величину с той, что была получена в первом пункте задания, и объяснить результаты.

2.2. С помощью вложенных циклов подсчитывается сумма элементов двумерного массива, которая возвращается затем в main. Необходимое для одного из операторов цикла количество элементов в строке массива указать числом (т.е. 3). В следующем задании будет разработан более универсальная программа.

Замечание

Хотя количество элементов в строке через аргумент не передается, его можно вычислить следующим образом. Пусть a2 обозначает формальный параметр, через который в функцию передается массив. По своему смыслу — это указатель на строку массива (т.е. на одномерный массив). Если к a2 применить операцию разадресации, то мы получим сам массив.

Теперь количество элементов в строке можно найти, если объем памяти, занимаемый строкой, поделить на размер одного элемента (sizeof(*a2)/sizeof(int)).

2.3 Проверить работу программы.

ЗАДАНИЕ 4 (универсальный вариант программы)

Разрабатывается другой вариант программы для задачи предыдущего задания. Для преобразований программы, сохранить файл задания 3 под другим именем.

1. Чтобы сделать функцию total2 более универсальной, критический для массива размер (число колонок) везде, где он встречается (в определении массива arr2, в определениях функции и прототипа, граничное значение в операторе цикла), задать с помощью именованной константы COLUMNS.

Определение константы COLUMNS выполнить в начале файла с помощью директивы

#define COLUMNS 3

Проверить работу программы.

Замечание

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

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

4. Чтобы убедиться, что внутри функции total2 обрабатываются непосредственно элементы массива arr2, добавить в total2 (перед оператором возврата) обнуления первой строки массива.

Соответственно, в функции main добавить после оператора вывода на экран подсчитанной суммы печать элементов первой строки массива arr2.

Изменить значение COLUMNS на 4, затем на 6. Убедиться, что сумма подсчитывается правильно, а количество выведенных обнуленных элементов меняется соответственно размеру.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]