Этот сайт использует cookies. Продолжение работы с сайтом означает, что Вы согласны!
Передача массивов и строк в функцию
Передача одномерных массивов и строк осуществляется с помощью указателей. Обратите внимание на то, что при вызове функции перед названием переменной не нужно добавлять оператор &
, так как название переменной содержит адрес первого элемента массива. Пример передачи C-строки приведен в листинге 12.10.
Листинг 12.10. Передача C-строки в функцию
#include <iostream>
void func1(char *s);
void func2(char s[]);
int main() {
char str[] = "String";
std::cout << sizeof(str) << std::endl; // 7
func1(str); // Оператор & перед str не указывается!!!
func2(str);
std::cout << str << std::endl; // strinG
return 0;
}
void func1(char *s) {
s[0] = 's'; // Изменяется значение элемента массива str
std::cout << sizeof(s) << std::endl;
// 8 (размер указателя), а не 7!!!
}
void func2(char s[]) {
s[5] = 'G'; // Изменяется значение элемента массива str
}
Объявление char *s
эквивалентно объявлению char s[]
. И в том и в другом случае объявляется указатель на тип char
. Чаще используется первый способ. Обратите внимание на значения, возвращаемые оператором sizeof
вне и внутри функции. Вне функции оператор возвращает размер всего символьного массива, в то время как внутри функции оператор sizeof
возвращает только размер указателя. Это происходит потому что внутри функции переменная s
является указателем, а не массивом. Поэтому, если внутри функции необходимо знать размер массива, то количество элементов (или размер в байтах) следует передавать в дополнительном параметре.
При передаче многомерного массива необходимо явным образом указывать все размеры (например, int a[2][4]
). Самый первый размер допускается не указывать (например, int a[][4]
). Пример передачи двумерного массива в функцию приведен в листинге 12.11.
Листинг 12.11. Передача двумерного массива
#include <iostream>
void func(int a[][4]);
int main() {
const int ARR_ROWS = 2, ARR_COLS = 4;
int i, j;
int arr[ARR_ROWS][ARR_COLS] = {
{1, 2, 3, 4},
{5, 6, 7, 8}
};
func(arr);
// Выводим значения
for (i = 0; i < ARR_ROWS; ++i) {
for (j = 0; j < ARR_COLS; ++j) {
std::cout.width(2); // Ширина поля
std::cout << arr[i][j];
}
std::cout << std::endl;
}
return 0;
}
void func(int a[][4]) { // или void func(int a[2][4])
a[0][0] = 80;
}
Такой способ передачи многомерного массива нельзя назвать универсальным, так как существует жесткая привязка к размеру. Одним из способов решения проблемы является создание дополнительного массива указателей. В этом случае в функцию передается адрес первого элемента массива указателей, а объявление параметра в функции выглядит так:
int *a[]
или так:
int **a
Пример передачи массива указателей приведен в листинге 12.12.
Листинг 12.12. Передача массива указателей
#include <iostream>
void func(int *a[], int rows, int cols);
int main() {
const int ARR_ROWS = 2, ARR_COLS = 4;
int arr[ARR_ROWS][ARR_COLS] = {
{1, 2, 3, 4},
{5, 6, 7, 8}
};
// Создаем массив указателей
int *parr[] = {arr[0], arr[1]};
// Передаем адрес массива указателей
func(parr, ARR_ROWS, ARR_COLS);
return 0;
}
void func(int *a[], int rows, int cols) {
// или void func(int **a, int rows, int cols)
for (int i = 0, j; i < rows; ++i) {
for (j = 0; j < cols; ++j) {
std::cout.width(2);
std::cout << a[i][j];
}
std::cout << std::endl;
}
}
Однако и этот способ имеет недостаток, так как нужно создавать дополнительный массив указателей. Наиболее приемлемым способом является передача двумерного массива как одномерного. В этом случае в функцию передается адрес первого элемента массива, а в параметре объявляется указатель. Так как все элементы двумерного массива располагаются в памяти последовательно, зная количество элементов или размеры можно вычислить положение текущего элемента, используя адресную арифметику. Пример передачи двумерного массива как одномерного приведен в листинге 12.13.
Листинг 12.13. Передача двумерного массива как одномерного
#include <iostream>
void func(int *pa, int rows, int cols);
int main() {
const int ARR_ROWS = 2, ARR_COLS = 4;
int arr[ARR_ROWS][ARR_COLS] = {
{1, 2, 3, 4},
{5, 6, 7, 8}
};
// Передаем в функцию адрес первого элемента массива
func(arr[0], ARR_ROWS, ARR_COLS);
return 0;
}
void func(int *pa, int rows, int cols) {
for (int i = 0, j; i < rows; ++i) {
for (j = 0; j < cols; ++j) {
std::cout.width(2);
// Вычисляем положение элемента
std::cout << *(pa + i * cols + j);
// std::cout << pa[i * cols + j];
}
std::cout << std::endl;
}
}
Передача в функцию массива C-строк осуществляется так же как передача массива указателей. Чтобы в функцию не передавать количество элементов можно при инициализации массива C-строк последнему элементу присвоить нулевой указатель. Этот элемент будет служить ориентиром конца массива. В качестве примера выведем все строки внутри функции (листинг 12.14).
Листинг 12.14. Передача массива C-строк
#include <iostream>
void func(const char *s[]);
int main() {
const char *str[] = {"String1", "String2", "String3",
nullptr // Вставляем нулевой указатель, чтобы был ориентир
};
func(str);
return 0;
}
void func(const char *s[]) { // или void func(const char **s)
while (*s) { // Выводим все строки
std::cout << *s << std::endl;
++s;
}
}
Реквизиты
ЮMoney (Yandex-деньги): 410011140483022
ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов