- •Объявление переменных в итерационных инструкциях и инструкциях выбора
- •Формальные параметры
- •Глобальные переменные
- •Функции
- •Вызов функций с массивами
- •Передача функциям строк
- •Аргументы функции main(): argc и argv
- •Передача числовых аргументов командной строки
- •Преобразование числовых строк в числа
- •Возврат значений
- •Функции, которые не возвращают значений (void-функции)
- •Функции, которые возвращают указатели
- •Прототипы функций
- •Подробнее о заголовках
- •Рекурсия
Вызов функций с массивами
Если массив является аргументом функции, то необходимо понимать, что при вызове такой функции ей передается только адрес первого элемента массива, а не полная его копия. Это означает, что объявление параметра должно иметь тип, совместимый с типом аргумента. Вообще существует три способа объявить параметр, который принимает указатель на массив.
Во-первых, параметр можно объявить как массив, тип и размер которого совпадает с типом и размером массива, используемого при вызове функции. Этот вариант объявления параметра-массива продемонстрирован в следующем примере.
#include <iostream>
using namespace std;
void display(int num[10]);
int main()
{
int t[10], i;
for(i=0; i<10; ++i) t[i]=i;
display(t); // Передаем функции массив t
return 0;
}
// Функция выводит все элементы массива.
void display(int num[10])
{
int i;
for(i=0; i<10; i++) cout << num[i] <<' ';
}
Несмотря на то что параметр num объявлен здесь как целочисленный массив, состоящий из 10 элементов, С++-компилятор автоматически преобразует его в указатель на целочисленное значение. Необходимость этого преобразования объясняется тем, что никакой параметр в действительности не может принять массив целиком. А так как будет передан один лишь указатель на массив, то функция должна иметь параметр, способный принять этот указатель.
Второй способ объявления параметра-массива состоит в его представлении в виде безразмерного массива, как показано ниже.
void display(int num[])
{
int i;
for(i=0; i<10; i++) cout << num[i] << ' ';
}
Здесь параметр num объявляется как целочисленный массив неизвестного размера.
Целочисленный массив при таком способе объявления также автоматически преобразуется С++-компилятором в указатель на целочисленное значение.
Третий способ объявления параметра-массива. При передаче массива функции ее параметр можно объявить как указатель. Как раз этот вариант чаще всего используется профессиональными программистами. Вот пример:
void display(int *num)
{
int i;
for(i=0; i<10; i++) cout << num[i] << ' ';
}
Возможность такого объявления параметра (в данном случае num) объясняется тем, что любой указатель (подобно массиву) можно индексировать с помощью символов квадратных скобок ([]). Таким образом, все три способа объявления параметра-массива приводятся к одинаковому результату, который можно выразить одним словом: указатель.
Однако отдельный элемент массива, используемый в качестве аргумента, обрабатывается подобно обычной переменной. Например, рассмотренную выше программу можно было бы переписать, не используя передачу целого массива:
#include <iostream>
using namespace std;
void display(int num);
int main()
{
int t[10],i;
for(i=0; i<10; ++i) t[i]=i;
for(i=0; i<10; i++) display(t[i]);
return 0;
}
// Функция выводит одно число.
void display(int num)
{
cout << num << ' ';
}
Как видите, параметр, используемый функцией display(), имеет тип int. Здесь не важно, что эта функция вызывается с использованием элемента массива, поскольку ей передается только один его элемент.
Помните, что, если массив используется в качестве аргумента функции, то функции передается адрес этого массива. Это означает, что код функции может потенциально изменить реальное содержимое массива, используемого при вызове функции. Например, в следующей программе функция cube() преобразует значение каждого элемента массива в куб этого значения. При вызове функции cube() в качестве первого аргумента необходимо передать адрес массива значений, подлежащих преобразованию, а в качестве второго — его размер.
#include <iostream>
using namespace std;
void cube(int *n, int num);
int main()
{
int i, nums[10];
for(i=0; i<10; i++) nums[i] = i+1;
cout << "Исходное содержимое массива: ";
for(i=0; i<10; i++) cout << nums[i] << ' ';
cout << '\n';
cube(nums, 10); // Вычисляем кубы значений.
cout << "Измененное содержимое: ";
for(i=0; i<10; i++) cout << nums[i] << ' ';
return 0;
}
void cube(int *n, int num)
{
while(num) {
*n = *n * *n * *n;
num--;
n++;
}
}
Результаты выполнения этой программы таковы.
Исходное содержимое массива: 12345678910
Измененное содержимое: 1 8 27 64 125 216 343 512 729 1000
Как видите, после обращения к функции cube() содержимое массива nums изменилось: каждый элемент стал равным кубу исходного значения. Другими словами, элементы массива nums были модифицированы инструкциями, составляющими тело функции cube(), поскольку ее параметр n указывает на массив nums.