Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,218
Записей в блоге: 2

Передать массив по значению

13.08.2026, 11:21. Показов 3294. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день

По ходу дела задал мелкий вопрос
Цитата Сообщение от Igor3D Посмотреть сообщение
Вопрос: как передать в ф-цию массив по значению? Понятно что легко обойти: сделать массив членом структуры и ее пихать по значению. Также понятно что передача массива по значению малополезна, а может и просто глупа. Но все-таки как, из любви к языку?
И народ как-то подозрительно промолчал.. Ладно, создадим тему, как положено

Спасибо
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
13.08.2026, 11:21
Ответы с готовыми решениями:

передать массив в функцию по значению
Подскажите,пожалуйста. Нужно с клавиатуры ввести число строк-столбцов ( т е они меняются в...

По заданным вещественному значению x и целому значению n вычислите x^n
Помогите с задачкой. Вот условие: По заданным вещественному значению x и целому значению n...

Не могу разобраться как передать корректно передать массив из функции в функцию
//--------------------------------------------------------------------------- #pragma hdrstop ...

34
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,218
Записей в блоге: 2
17.08.2026, 00:03  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Recrut_rf Посмотреть сообщение
у меня складывается впечатление, что всё, что связано с массивами да и указателями в том числе - в современном программировании на С++ давным давно упростилось до безобразия уровня какой-нибудь Jаva или C#.
А мы так и хотим
C++
1
2
3
4
5
typedef int IArr4[4];
 
void foo1( const IArr4 & a );  // работает
void foo2( IArr4 & a );  // работает
void foo3( IArr4 a );  // работает, но не по значению
Задача - создать такой IArr4 чтобы и foo3 работало стандартно, как положено. Причем "питаться" (вызываться) эти ф-ции должны (также) от сишных массивов, т.е.
C++
1
2
3
4
int a[4];
foo1(a); 
foo2(a); 
foo3(a);
Вместо typedef можно писать любые классы, операторы и.т.п. Разумеется данные массивов должны копироваться только при необходимости
0
 Аватар для Наталья8
638 / 396 / 68
Регистрация: 09.03.2016
Сообщений: 4,370
17.08.2026, 03:21
Что бы решить эту задачу,
необходимо написать это на листе плотной бумаги.

0
 Аватар для Наталья8
638 / 396 / 68
Регистрация: 09.03.2016
Сообщений: 4,370
17.08.2026, 12:20
Основное - когда пишешь, правильно понимать что ты делаешь
и что там будет происходить по запуску приложения.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,218
Записей в блоге: 2
23.08.2026, 19:43  [ТС]
Напр такой сюжет. Увидел рекомендацию типа
Для нового кода предпочитайте std::array вместо сишных массивов
Хорошо, так и сделаю
C++
1
2
3
using StdArr4 = std::array<int, 4>;
 
void foo( StdArr4 a );  // хочу по значению
Да, но истреблять все сишные массивы в своем коде я вовсе не обязан, а иногда и просто не могу, не от меня зависит. Как использовать ф-цию foo для сишного массива? Почему не так
C++
1
2
3
4
const StdArr4 & ToStdArr4( const int * a )
{
    return *(StdArr4 *) a;
}
Тогда вызов
C++
1
2
3
int a[4];
...
foo(ToStdArr4(a));
Правду сказать, в рабочем коде я бы так делать не стал. Слишком подозрительно такое приведение, "дает почву" для разговоров об alignment, strict aliasing и.т.п. Тем более какой-то острой необходимости в этом трюке нет, ну тупенько сделал копию в ToStdArr4, компилятор наверняка соптимизирует передачу. Но с др стороны, а почему это не должно работать? Что здесь такого уж плохого? Доказать некорректность этого кода я не могу. А Вы?
0
фрилансер
 Аватар для Алексей1153
6506 / 5756 / 1134
Регистрация: 11.10.2019
Сообщений: 15,404
23.08.2026, 19:51
Цитата Сообщение от Igor3D Посмотреть сообщение
return *(StdArr4 *) a;
это неопределённое поведение. Объект типа int интерпретируется как объект типа std::array<int, 4>

Цитата Сообщение от Igor3D Посмотреть сообщение
Да, но истреблять все сишные массивы в своем коде я вовсе не обязан, а иногда и просто не могу, не от меня зависит.
вот именно поэтому Степанов и придумал гениальный ход с итераторами для STL - чтобы не нужно было думать, какой контейнер передаётся в функцию.

Передаются итераторы и всё
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,218
Записей в блоге: 2
23.08.2026, 21:58  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
это неопределённое поведение. Объект типа int интерпретируется как объект типа std::array<int, 4>
И что? Чем это некорректно если массив гарантированно int?
Цитата Сообщение от Алексей1153 Посмотреть сообщение
вот именно поэтому Степанов и придумал гениальный ход с итераторами для STL - чтобы не нужно было думать, какой контейнер передаётся в функцию.

Передаются итераторы и всё
Ну и как должна выглядеть ф-ция foo выше (объявление) с этой гениальной итераторной парой?
0
фрилансер
 Аватар для Алексей1153
6506 / 5756 / 1134
Регистрация: 11.10.2019
Сообщений: 15,404
23.08.2026, 23:07
Цитата Сообщение от Igor3D Посмотреть сообщение
Чем это некорректно
неопределённым поведением же

Цитата Сообщение от Igor3D Посмотреть сообщение
Ну и как должна выглядеть ф-ция foo выше
как угодно, учитывая итераторы

Ну а когда нужно скопировать контейнер, нужно его просто скопировать
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
24.08.2026, 05:50
Цитата Сообщение от Алексей1153 Посмотреть сообщение
неопределённым поведением же
Это интересный вопрос.

Стандарт языка вводит такое свойство, как pointer-interconvertible. В частности, если класс имеет standard layout, то указатель на объект такого класса и указатель на его первый нестатический подобъект являются pointer-interconvertible. Далее, преобразование между такими указателями определены для двойного static_cast, то есть static_cast через посредство void *. При этом reinterpret_cast для указателей на объектные типы определяется именно как такой двойной static_cast.

Стандарт не описывает внутреннее устройство std::array буквально, но вроде гарантирует, что этот тип должен вести себя как standard layout класс с обычным сишным массивом внутри. В таком случае, если я ничего не упускаю, такое преобразование и доступ являются вполне легальными и не вызывают неопределенного поведения.
0
фрилансер
 Аватар для Алексей1153
6506 / 5756 / 1134
Регистрация: 11.10.2019
Сообщений: 15,404
24.08.2026, 08:34
TheCalligrapher, ну, не знаю, я бы не стал такую бомбу в код закладывать,
ведь можно обойтись без таких кастов.

И кто гарантирует, что Igor3D не станет с другими классами такое делать


Igor3D,
Ну, например, вот функция принимает массив по ссылке и возвращает его копию, завёрнутую - да во что больше нравится. Например, тот же std::array

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <array>
 
template<typename T, size_t size>
auto copy_array(const T (&src)[size])
{
    std::array<T,size> a;
    std::copy(std::begin(src),std::end(src),a.begin());
    return a;
}
 
int main()
{
    struct A
    {
        int N{};
    };
    
    A array[42];
    
    auto a = copy_array(array);
}
Кстати, я тут внезапно подумал вот, о чём.

Например, поле N было бы неинициализировано.

Тогда будет ли проблема в std::copy ?

И была бы такая же проблема, если ли бы массив можно было просто копировать оператором =
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
24.08.2026, 10:16
Цитата Сообщение от Алексей1153 Посмотреть сообщение
ведь можно обойтись без таких кастов.
Можно... Но задача состоит в том, чтобы передать С-массив как std::array в функцию foo по значению и при этом, желательно, избежать лишних копий/лишних копирований. Ваш вариант с copy_array будет (?) создавать лишнюю копию исходных данных, то есть будет создавать возвращаемое значение функции copy_array, которое затем будет еще раз (!) копироваться в параметр вызываемой функции foo.

Без лишнего копирования вызвать такую функцию можно так

C++
1
2
3
4
void foo(std::array<A, 42> a);
...
A array[42];
foo({ array[0], array[1] /* ...и так 42 раза */ });
что, однако, можно автоматизировать через fold expressions

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct A { int N{}; };
 
void foo(std::array<A, 42> a)
{
  /* ... */
}
 
template <std::size_t ...I, std::size_t N> void call_foo_impl(const A (&array)[N], std::index_sequence<I...>)
{
  foo({ (array[I])... });
}
 
template <std::size_t N> void foo(const A (&array)[N])
{
  call_foo_impl(array, std::make_index_sequence<N>{});
}
 
int main()
{
  A array[42] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
  foo(array);
}
1
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,218
Записей в блоге: 2
24.08.2026, 18:25  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Кстати, я тут внезапно подумал вот, о чём.
Например, поле N было бы неинициализировано.
Тогда будет ли проблема в std::copy ?
Нет, как записаны данные - копированию все равно
Цитата Сообщение от Алексей1153 Посмотреть сообщение
И была бы такая же проблема, если ли бы массив можно было просто копировать оператором =
Да, если проблема = сырые данные
Цитата Сообщение от Алексей1153 Посмотреть сообщение
Ну, например, вот функция принимает массив по ссылке и возвращает его копию, завёрнутую - да во что больше нравится. Например, тот же std::array
Не так просто. При передаче по значению просматривается двойное копирование, первый раз std::copy, второй при передаче этого аргумента. Наверняка компилятор это схлопнет, но все же. А главное - передача по значению случай редкий, зато напр таких вызовов будет полно
C++
1
void foo2( const StdArr4 & data );
Очевидно здесь копирование исходного сишного массива неуместно

Не по теме:

Цитата Сообщение от Алексей1153 Посмотреть сообщение
И кто гарантирует, что Igor3D не станет с другими классами такое делать:)
Не надо примерять роль "старшего брата", Вы на него точно не похожи :)


Цитата Сообщение от Алексей1153 Посмотреть сообщение
как угодно, учитывая итераторы
Это так гениально (итераторная пара) что примера под рукой не находится Понятно. А эту пару никогда не любил, и, по моим наблюдениям, не я один. И таких гордых задач "супергибкости" не ставилось, предполагается что массив состоит из элементов размера sizeof следующих подряд

Стандарт (в конце-концов) признал что "тривиально копируемые" объекты могут быть созданы из "дампа памяти", это корректное действие (хотя всю жизнь так делали). А тогда и приведение выше корректно, ведь там просто назначается адрес для данных что бьются по формату. Да, выглядит коряво/ужасно, понятно что лучше так не делать. Ну так предложите что-то другое, содержательное вместо наивного копирования
0
фрилансер
 Аватар для Алексей1153
6506 / 5756 / 1134
Регистрация: 11.10.2019
Сообщений: 15,404
24.08.2026, 18:33
Цитата Сообщение от Igor3D Посмотреть сообщение
что примера под рукой не находится
пример - это под конкретный случай.

Итераторы - это, как раз, чтобы вообще не копировать контейнер.

А тут, я так понял, сильно хочется именно скопировать
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,218
Записей в блоге: 2
24.08.2026, 19:08  [ТС]
Цитата Сообщение от Алексей1153 Посмотреть сообщение
А тут, я так понял, сильно хочется именно скопировать
Ну как.. передача "по значению" предполагает копирование автоматом, хотелось бы этим воспользоваться

Конечно всегда есть простой и хороший вариант: передавать адрес первого эл-та (возможно const) + число эл-тов, т.е.
C++
1
void foo3( const int * arr, size_t count );
А надо по значению - не выделываться а внутри ф-ции скопировать, таких вызовов немного. Но всегда найдутся пижоны типа
Смотрите, смотрите, да он же пишет "как на С", новыми фичами не владеет !
И в этом что-то есть (пусть совсем немного, в основном понты и снобизм). Действительно, выглядит архаично, где же новизна/крутизна?
0
фрилансер
 Аватар для Алексей1153
6506 / 5756 / 1134
Регистрация: 11.10.2019
Сообщений: 15,404
24.08.2026, 19:25
Цитата Сообщение от Igor3D Посмотреть сообщение
Также понятно что передача массива по значению малополезна, а может и просто глупа


а вот стиль общения отталкивает хоть что-нибудь обсуждать

Что тогда удивляться ?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13233 / 6865 / 1827
Регистрация: 18.10.2014
Сообщений: 17,398
24.08.2026, 19:47
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Ваш вариант с copy_array будет (?) создавать лишнюю копию исходных данных, то есть будет создавать возвращаемое значение функции copy_array, которое затем будет еще раз (!) копироваться в параметр вызываемой функции foo

... хотя стандарт языка не запрещает существования такой промежуточной копии, он также и не требует ее существования. Компиляторы в состоянии ее устранить. Такое лишнее копирование - скорее всего побочный эффект требований какого-нибудь ABI. Очень странно видеть, что ни один из компиляторов не осмеливается в такой ситуации устранить промежуточную копию.

---

Да, точно: достаточно объявить функцию-получатель foo статической, то есть вывести ее из-под требований ABI, как лишняя копия исчезает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.08.2026, 19:47

Как передать значение параметра функции одного экзешника значению параметра функции другому екзешнику?
Здравствуйте! Ребята подскажите по такому вопросу. У меня есть консольное приложение в...

Как передать массив в массив с указателем
Как передать массив в массив с указателем тоесть например массив double c в массив **а в этой...

Массив: передать динамический массив в функцию и записать в каждый элемент строку из файла
задача: передать динамический массив в функцию, и записать в каждый элемент строку из файла....

Передать массив I(10) в массив J(10) в обратной последовательности
помогите пожалуйта решить пару задач, задачи не сложные, но я не могу в них разобраться...

Передать массив I в массив J в обратной последовательности
Передать массив I(10) в массив J(10) в обратной последовательности. #include &lt;iostream&gt; using...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru