1 вариант:
void func(int ** &arr, int size) {
arr = new int * [size];
<...>
}
int main() {
int size = <...>;
int **arr;
func(arr, size);
}
2 вариант:
void func(int **arr, int size) {
<...>
}
int main() {
int size = <...>;
int **arr = new int * [size];
func(arr, size);
}
Объясните, пожалуйста, почему в первом варианте мы в функции выделяем память под массив и передаем arr
по ссылке, а во втором варианте в main
выделяем память и тогда уже не надо по ссылке в функцию передавать arr
. Не понимаю, как тут работают указатели.
В первом случае мы объявляем переменную arr
типа int **
. Передаем ссылку на нее в функцию func
и уже там присваиваем ей значение.
Во втором случае мы объявляем переменную arr
типа int **
и сразу присваиваем ей значение — указатель на выделенную память.
Таким и образом, и первый и второй вариант код верный. Какой именно способ использовать зависит от ваших предпочтений и, собственно, решаемой этим кодом задачи.
…и тогда уже не надо по ссылке в функцию передавать arr
…
В первом случае мы могли бы воспользоваться указателем, а не ссылкой:
void func(int ***arr, size_t size) {
*arr = new int * [size];
<...>
}
Однако никто не мешает вам и во втором случае передавать arr
по ссылке.
Никто не мешает в первом случае тоже выделять память в main
. Но вот во втором случае выделять память в func
не получится.
Смотрите, совсем простой пример:
#include <iostream>
void foo(int x)
{
x = 1;
}
int main()
{
int y = 0;
foo(y);
std::cout << y << '\n';
}
Что напечатает этот код, 1
? Нет, 0
, потому что x
и y
- разные переменные. А если сделать void foo(int &x)
, тогда результат будет 1
.
С указателями то же самое.
Если вы внутри void func(int **arr, int size)
сделаете arr = new ...
, то переменная int **arr
в main
не изменится, и из main
вы никак не получите доступ к этой памяти.
Однако! Если вы меняете arr[i]
или *arr
, то эти изменения в любом случае будут видны снаружи функции. При передаче arr
из main
в void func(int **arr, int size)
, копируется только сам указатель, но не то, на что он указывает (т.е. копируется адрес, записанный в указателе). То есть изменения самого указателя не будут заметны снаружи функции, в отличие от изменений того, на что он указывает.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Я хочу подключить библиотеку sfeMovie (для отображения видео) к проектуДелаю всё по инструкции: http://sfemovie
У меня есть некий абстрактный класс, назовем его AbstrУ него есть чисто виртуальная функция, что выводит на экран принятый указатель (разыменовывает...
У меня есть 6 штук блоков, каждые называются одинаково, только значения в теге <b>12</b> разные