Передача одномерных массивов в функции
При передаче одномерных массивов в функции следует вызывать функцию с именем массива без индекса. В результате этого передается адрес первого элемента массива. В С невозможно передать весь массив как аргумент. Вместо этого автоматически передается указатель. Следующий пример передает адрес i в func1();
Если функция получает одномерный массив, то можно объявить формальный параметр как указатель, как массив с фиксированной длиной или как безразмерный массив. Например, для передачи i в функцию func1() можно объявить func1() одним из следующих способов:
void fun1(int a[10]) /* массив с фиксированной длиной */
.
>
void fun1(int a []) /* безразмерный массив */
.
>
Все три способа объявления сообщают компилятору, что предполагается получение указателя на целое, В первом объявлении используется указатель. Во втором — стандартный способ объявления массива. В третьем — модифицированная версия объявления массива, указывающая на то, что предполагается получение массива типа int некоторой длины. Не имеет значения длина передаваемого массива, поскольку С не выполняет проверку выхода за границы массива. Фактически
также будет работать, поскольку компилятор создает код, указывающий func1() о получении указателя (на самом деле не создается 32-элементный массив).
Как передать одномерный массив в функцию c
Использование массива как параметра функции не вызывает ни каких трудностей. Как было сказано ранее, массив в подпрограмму всегда передаётся по адресу, поэтому достаточно при вызове функции указать адрес начала массива или адрес того элемента, начиная с которого предполагается обрабатывать массив.
Пример . Написать программу, которая будет вызывать функцию для вывода на печать элементов массива.
Возможный вариант решения:
using namespace std;
void print(int x[], int n);
void print(int x[], int n)
При вызове функции оператором
в неё передаётся адрес начала массива x и количество элементов n . Количество элементов n передаётся по значению и здесь всё должно быть понятно, но вот с передачей самого массива может быть некоторое непонимание, которое необходимо устранить.
Итак, массив в функцию должен передаваться по адресу, и нам необходим в подпрограмме весь массив, поэтому логично вызов функции записать так:
С учётом того, что массив в подпрограмму чаще всего передаётся весь и с начала, разработчики языка запись вида &x[0] сократили до x , т.е. обращение к массиву по имени эквивалентно обращению по адресу к элементу с индексом 0 .
В заголовке функции
void print(int x[], int n) // 1-й вариант
два формальных параметра. Запись x[] говорит о том, что в подпрограмму передаётся именно массив.
Заголовок может выглядеть и так:
void print(int *x, int n) // 2-й вариант
Массив передаётся по адресу, поэтому и записываем первый параметр как адрес на объект типа int . Этот объект-указатель принимает адрес того элемента массива, который вычисляется в вызывающей функции (например, в main() ).
Какую форму использовать? Это дело вкуса. Компилятор рассматривает 1-й вариант как эквивалент 2-го, хотя для человека нагляднее именно 1-й вариант. По нему видно, что формальный параметр — это именно массив, а не указатель, например, на одиночный элемент.
Трактовка при вызове x как &x[0] позволяет при необходимости передать в подпрограмму не весь массив, а только его часть, начиная с какого-либо адреса. Например, вызов
приводит к выводу на экран монитора трёх элементов массива, начиная с элемента с индексом 2 . При этом сама функция не требует каких либо доработок. В этом плане языки С/С++ гораздо удобнее многих других языков. Так, в Паскале или Бейсике пришлось бы передавать в подпрограмму ещё один параметр — номер элемента, с которого необходимо начать обработку массива, а затем этот номер использовать в операторе цикла.
Матрица как параметр функции
Передача в подпрограмму матрицы в качестве параметра несколько сложнее, чем передача одномерного массива.
Матрица также передаётся по адресу. При вызове функции достаточно указать имя матрицы (это будет адресом начала двумерного массива), но как задать описание матрицы в списке формальных параметров? Матрица, как было сказано ранее, — это массив из массивов. Поэтому можно попробовать записать формальный параметр так:
К сожалению, это работать не будет. Первая пара пустых квадратных скобок указывает на то, что имеем дело с массивом. Это допустимо. Вторая пара квадратных скобок как признак того, что это тоже массив, сгенерирует ошибку. Здесь компилятор захочет больше конкретики. Массив из неизвестно каких массивов его не устроит. Во вторых скобках надо записать константу, чтобы компилятор мог понять, как память в матрице распределяется по строкам и столбцам.
Таким образом, допустима запись
Рассмотрим небольшой пример, поясняющий сказанное выше.
Пример . Написать и протестировать функцию вывода значений целочисленной матрицы на экран монитора.
Возможный вариант реализации:
using namespace std;
void PrintMatr(int a[][M], int n, int m);
Передача статического одномерного массива определённого размера в функцию
Я хочу передать в функцию статический массив определённого размера, который будет проверяться при компиляции.
#include void print(int arr[3]) < std::cout std::cout int main() < int staticArr2[2] = ; int staticArr3[3] = ; std::cout
Но вот конструкция int arr[3] воспринимается как int * в объявлении входных параметров функции. Подскажите, как можно реализовать передачу массива конкретного размера.
Отслеживать
32k 19 19 золотых знаков 79 79 серебряных знаков 105 105 бронзовых знаков
задан 18 дек 2015 в 15:24
53 1 1 серебряный знак 5 5 бронзовых знаков
Прекрасный вопрос, кстати!
18 дек 2015 в 19:15
6 ответов 6
Сортировка: Сброс на вариант по умолчанию
Можно воспользоваться шаблонами для того, чтобы передавать массив как массив, а не как указатель. При таком вызове сохраняется информация о размере массива. Если дополнить код вызовом static_assert , то ошибка будет выдаваться во время компиляции.
template void print(int (&arr)[N]) < static_assert(N == 3, "Array must contain 3 elements"); // Проверка выполняется // во время компиляции std::cout std::cout
При попытке передать массив из двух элементов будет выведена ошибка:
prog.cpp: In instantiation of 'void print(int (&)[N]) [with unsigned int N = 2u]': prog.cpp:22:21: required from here prog.cpp:6:2: error: static assertion failed: Array must contain 3 elements static_assert(N == 3, "Array must contain 3 elements"); ^
Отслеживать
ответ дан 18 дек 2015 в 15:41
32k 19 19 золотых знаков 79 79 серебряных знаков 105 105 бронзовых знаков
Большое спасибо. Такую шаблонную конструкцию можно воспринимать только как с++ магию, или здесь есть какая то логика? Подскажите пожалуйста, где можно найти дополнительную информацию об этом.
18 дек 2015 в 15:46
@Rekiro Что считать магией, а что нет — это решает каждый сам для себя. Стандартная библиотка, boost и прочие привычные вещи понапичканы мозговыносящими конструкциями на шаблонах — они становятся из-за этого магией? Ну а вычисление размера массива с помощью такого шаблона есть в VC++ в виде _countof . stackoverflow.com/q/4108313 На вопрос "почему" во всех деталях, к сожалению, ответить не могу. Обычно ответ звучит как "потому что стандарт такой", а я ни разу не специалист по нюансам стандарта.
18 дек 2015 в 15:54
@Discord, ну и как этим пользоваться? Сделайте законченый рабочий пример (думаю, Вы сами убедитесь, что кресты это бред).
18 дек 2015 в 16:03
@avp Не понял. Что значит "как пользоваться"? Вызовы этой функции есть в вопросе. Про бред вообще не понял. вы же плюсовик? о_О
18 дек 2015 в 16:05
Пример с main, который компилируется и печатает значение sizeof. (а я не не "плюсовик", а "сишник").
18 дек 2015 в 16:07
Конкретный размер передается отдельным параметром.
В функцию надо передавать два параметра:
- ссылку на первый элемент массива (это имя массива без квадратных скобок
- размерность массива.
Отслеживать
ответ дан 18 дек 2015 в 15:30
user453575457 user453575457
2,899 2 2 золотых знака 20 20 серебряных знаков 41 41 бронзовый знак
По логике программы функция знает массив какой размерности ей передаётся. И поэтому мне необходимо чтобы передавался именно массив, а не указатель
18 дек 2015 в 15:33
"Именно массив" это и есть указатель на ячейки памяти в которых хранятся данные, это можно сказать разновидность указателя.
18 дек 2015 в 15:34
Если уж так надо именно определенный один объект передать - можно и в структуру и в вектор и в список массив затолкать и много куда еще, и передавать уже этот объект. Но у вас я так понимаю задача не в этом, а в простой обычной передаче. Так вот просто и обычно - передать указатель/ссылку.
18 дек 2015 в 15:38
можно завернуть массив в структуру и передавать экземпляр структуры в качестве аргумента функции:
struct Array3 < int items[3]; >; void print(struct Array3 arr) < // code here >
Отслеживать
ответ дан 18 дек 2015 в 15:34
Vitali Falileev Vitali Falileev
374 1 1 серебряный знак 5 5 бронзовых знаков
Только надо не забывать, что такой массив будет передаваться "по значению" (в стек будет записана его копия) и соответственно все изменения будут утеряны (если не возвращать его обратно и не присваивать оригиналу). Однако, действительно, этот метод с небольшой модификацией можно использовать, если передавать в функцию адрес структуры.
18 дек 2015 в 15:53
А Вы надеялись увидеть 12?
С т.з. языка аргумент функции, хоть и описывающий массив с указанием размера все равно является указалем.
И ведь на самом же деле в функцию в стеке (или в некоторых архитектурах в одном из регистров) передается указатель, который в 32-bit системах имеет размер 4 байта (которые Вы и видите на печати).
Причем, даже в gcc, который "на самом деле понимает" размеры массивов (точнее низшие размерности многомерных массивов), например, вот такой код --
int f (int m, int n, int a[m][n]) < printf("n = %d a[n] = %ld\n", n, (long)sizeof(a)); int i, j; for (i = 0; i < m; i++) for (j = 0; j < n || !puts(""); j++) printf("%d ", a[i][j]); // обратите внимание он (компайлер) в самом деле учитывает количество элементов в строке матрицы. return 0; >int main (int ac, char *av[]) < static int c[2][5] = < , >; f(2, 5, c); >
все равно sizeof(a) выдает 4.
Передача массивов в функцию (одномерные массивы)
Добрый вечер вы не моглибы помочь, написать програму, как для чайника, для меня.
задание
Передача массивов в функцию (одномерные массивы)
Дан одномерный массив, состоящий из N вещественных элементов.
1. Найти максимальный элемент.
2. Вычислить сумму четных элементов массива.
Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

передача массивов в функцию (одномерные массивы)
помогите пожалуйста. нахожу похожие коды, но все равно не получаеться. дан одномерный массив.
Передача массивов в функцию (одномерные массивы)
Кто-нибудь может сделать? Заранее блогодарю. Передача массивов в функцию (одномерные массивы).
Передача массивов в функцию (одномерные массивы)
1 Дан одномерный массив, состоящий из N вещественных элементов. -Найти минимальный элемент.
Передача массивов в функцию (одномерные массивы)
Определить функции, выполняющие действия 17. Дан одномерный массив, состоящий из N целочисленных.
Регистрация: 24.05.2012
Сообщений: 23

Сообщение было отмечено kolya999 как решение
Решение
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#include #include using namespace std; double maximum(int n, double *M){ double result=M[0]; for(int i=1; in; i++) if(M[i]>result) result=M[i]; return result; } double sum_of_even_elements(int n, double *M){ double result=0; for(int i=0; in; i+=2) result+=M[i]; return result; } int main() { const int n=5; double M[n]; /* задать элементы матрицы */ cout<"Maximal element of the array is "( n, M); cout<"Sum of the even elements of the array is "( n, M); getch(); return 0; }
Форумчанин
![]()
![]()
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
#include int maxInArray(int *arr, int N) { int max = arr[0]; // максимум равен первому элементу for (int i=0; i N; i++) // в цикле перибираем элементы массива if(arr[i] > max) max = arr[i]; // если элемент больше максимума, то максимум равен этому элементу return max; } int evenSum(int *arr, int N) { int sum = 0; // сумма равна 0 for (int i=0; i N; i++) // в цикле перибираем элементы массива // если остаток от деления элемента на 2 равен 0, то прибавляем его к сумме if(arr[i] % 2 == 0) sum += arr[i]; return sum; // возвращаем сумму } int main() { const int N = 10; // размер массива int A[N]; for (int i=0; i N; i++) { A[i] = i + 1; // элемент массива равен своему индексу + 1 std::cout [i] <" "; // выводим элемент на экран } // выводим на экран результаты функций std::cout <"\nMax is: " ( A, N) <"\nSum of even: " ( A, N); return 0; }