Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / C++ Новый топик    Ответить
 передача в функцию ссылок, укзателей  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Добрый день .

Из определения ссылки можно понять, что это нечто тоже самое что и указатель за исключением синтаксиса, ну там отсутствия разиеменования, отсутствия арифметики подобно указателям , а может чего-то ещё важного , но я пока этого не знаю.
На данный момент мечтаю понять как происходит передача ссылки в функцию и передача указателя в функцию.
вот смотрите на эту реализацию вставки в массив элемента справа . есть 2 реализации , а именно при помощи ссылки push_backref и при помощи указателей push_backptr (последняя реализация не рабочая):

void printArray(int* arr1, int size)
{
	for (int i = 0; i <= size - 1; i++)
		std::cout << arr1[i] << ' '; 
	std::cout << std::endl;
}


void push_backref(int * &arr1, int& size, const int value)
{
	int* newArray = new int[size + 1];
	newArray[size] = value;
	for (int i = 0; i < size; i++)
	  newArray[i] = arr1[i];
	size++;
	delete[]arr1;
		arr1 = newArray;
}


void push_backptr(int *arr1, int& size, const int value)
{
	int* newArray = new int[size + 1];
	newArray[size] = value;
	for (int i = 0; i < size; i++)
		newArray[i] = arr1[i];
	size++;
	delete[]arr1;
	arr1 = newArray;
}


void fillArray(int* arr1, int const size)
{
	for (int i = 0; i <= size - 1; i++)
		arr1[i] = rand();
}


int main()
{
	int SIZE = 5;
	int* arr = new int[SIZE];

	fillArray(arr, SIZE); //заполняем массив лишь бы был не мусор
	printArray(arr, SIZE); //печать массива на экран
	//push_backref(arr, SIZE, 1000);
	push_backpntr(arr, SIZE, 1000);
	printArray(arr, SIZE);
	
}


я делаю :
int* arr = new int[SIZE];
затем заполняю массив :
void fillArray(int* arr1, int const size)

а затем непонятно, что происходит когда выполняется передача параметров *arr1 и *&arr1 в функции соответственно:
void push_backptr(int *arr1
и когда делаем
void push_backref(int * &arr1

а именно не понятно, что представляют arr1 в телах обоих функций . в чём их разница.
могу предполагать , что и в одной и в другой процедуре создается локальные копии которые обе имеют связь с динамическим массивом.
затем дойдя до строчки :
delete[]arr1;


потом мы уничтожаем объекты созданные
int* arr = new int[SIZE];
а потом после этого
arr1 = newArray;
ничего не работает в push_backptr (хотя работает в похожей push_backptr :) )
и работает в в push_backref
20 фев 20, 16:51    [22084008]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6491
andron81,

void push_backptr(int **arr1, int& size, const int value)
{
	...
	delete[] *arr1;
	*arr1 = newArray;
}
20 фев 20, 17:46    [22084052]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Anatoly Moskovsky
andron81,

void push_backptr(int **arr1, int& size, const int value)
{
	...
	delete[] *arr1;
	*arr1 = newArray;
}


А прокомментировать? :))

Мне что это ** arr, что это *& arr одинакого выносит мозг:))

Самое главное я не понимае чем физически являюся эти локальные копии в функциях
20 фев 20, 18:01    [22084066]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
Dima T
Member

Откуда:
Сообщений: 14727
andron81
А прокомментировать? :))

ИМХО это основы С/С++, их лучше в книжках читать. Указатель и указатель на указатель это разные вещи. Странно что откомпилировалось.

PS Аналог ссылки на указатель это указатель на указатель

Сообщение было отредактировано: 20 фев 20, 18:30
20 фев 20, 18:24    [22084093]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 49957

andron81
Мне что это ** arr, что это *& arr одинакого выносит мозг:))

Читай справа налево тогда.

Нет, это не шутка, а реальная рекомендация из учебников для чайников.

andron81
Самое главное я не понимае чем физически являюся эти локальные копии в функциях

Тогда тебе следует изучить ассебмлер и читать результат компиляции (ключик --save-temps
рулит).

Posted via ActualForum NNTP Server 1.5

20 фев 20, 18:48    [22084114]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6491
andron81,

Когда вы передаете что-то аргументом в функцию - оно копируется, и функция работает с копией.
Например

void push_backptr(int *arr1, int& size, const int value)
{
	int* newArray = new int[size + 1];
...
	delete[] *arr1;     
	arr1 = newArray;
}
...
int* arr = new int[SIZE];
push_backpntr(arr, SIZE, 1000);

Здесь, arr1 внутри функции это копия указателя arr переданного параметром. Обе копии указывают на один и тот же блок памяти.
Когда вы его меняете внутри функции, то вы меняете копию, и вызывающий код видит старый указатель, который к тому же указывает в несуществующий уже старый массив, потому что функция удалила его.
Поэтому, вам надо реализовать передачу измененного указателя обратно в вызывающий код.
Для этого можно объявить параметр ссылкой int * &arr1, или указателем на указатель int **arr1.
В первом случае вызывается так же. А во втором случае вызывать с помощью оператора получения адреса & (указатель - это адрес): push_backpntr(&arr, SIZE, 1000); Ну а внутри функции разыменовывать этот указатель на указатель, получая просто исходный указатель: *arr1 = newArray;
20 фев 20, 18:54    [22084123]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Dimitry Sibiryakov

Читай справа налево тогда.

Нет, это не шутка, а реальная рекомендация из учебников для чайников.



Дайте название книги и автора, пожалуйста:)
20 фев 20, 19:00    [22084132]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 49957

andron81
Дайте название книги и автора, пожалуйста:)

Чтоб я ещё помнил такие мелочи... Но рекомендую
https://en.cppreference.com/w/cpp/language/basic_concepts

Posted via ActualForum NNTP Server 1.5

20 фев 20, 19:05    [22084136]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
Dima T
Member

Откуда:
Сообщений: 14727
andron81
Дайте название книги и автора, пожалуйста:)

Классика https://www.ozon.ru/context/detail/id/150133610/
20 фев 20, 19:05    [22084137]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 49957

Да и гугль не подводит:
https://www.codeproject.com/Articles/7042/How-to-interpret-complex-C-C-declarations#right_left_rule

Posted via ActualForum NNTP Server 1.5

20 фев 20, 19:09    [22084139]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
Dima T
Member

Откуда:
Сообщений: 14727
Dimitry Sibiryakov, твои ссылки не для чайников, не пугай ТС`а ))
20 фев 20, 19:14    [22084143]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Anatoly Moskovsky
andron81,

Когда вы передаете что-то аргументом в функцию - оно копируется, и функция работает с копией.
Например

void push_backptr(int *arr1, int& size, const int value)
{
	int* newArray = new int[size + 1];
...
	delete[] *arr1;     
	arr1 = newArray;
}
...
int* arr = new int[SIZE];
push_backpntr(arr, SIZE, 1000);

Здесь, arr1 внутри функции это копия указателя arr переданного параметром. Обе копии указывают на один и тот же блок памяти.
Когда вы его меняете внутри функции, то вы меняете копию, и вызывающий код видит старый указатель, который к тому же указывает в несуществующий уже старый массив, потому что функция удалила его.
Поэтому, вам надо реализовать передачу измененного указателя обратно в вызывающий код.
Для этого можно объявить параметр ссылкой int * &arr1, или указателем на указатель int **arr1.
В первом случае вызывается так же. А во втором случае вызывать с помощью оператора получения адреса & (указатель - это адрес): push_backpntr(&arr, SIZE, 1000); Ну а внутри функции разыменовывать этот указатель на указатель, получая просто исходный указатель: *arr1 = newArray;


может быть вы тут ошиблись в коде и параметры функции хотели описать так :
void push_backptr(int **arr1, int& size, const int value)


то есть я верно понимаю, что arr1 это локальная переменная - копия содержащая адрес в которой лежит перемеменная arr(arr из main) . и этот адрес не умирает, когда мы делаем delete в функции. и за счет этого мы в ячейку по этому выжившему адресу кладем уже ссылку на первый элемент массива вот так :
*arr1 = newArray;

если всё верно , то я только не понимаю почему не работает копирование :
for (int i = 0; i < size; i++)
newArray[i] = * arr1[i];

void push_backpntr(int **arr1, int& size, const int value)
{
	int* newArray = new int[size + 1];
	newArray[size] = value;
	for (int i = 0; i < size-1; i++)
		newArray[i] = *arr1[i];
	size++;
	delete[]*arr1;
	*arr1 = newArray;
}

int main()
{
	int SIZE = 5;
	int* arr;
	arr  = new int[SIZE];


	fillArray(arr, SIZE);
	printArray(arr, SIZE);
	push_backpntr(&arr, SIZE, 1000); 
	//push_backref(arr, SIZE, 1000);
	printArray(arr, SIZE);
	
}


Сообщение было отредактировано: 21 фев 20, 15:20
21 фев 20, 15:14    [22084666]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6491
andron81,

newArray[i] = (*arr1)[i];
21 фев 20, 15:47    [22084714]     Ответить | Цитировать Сообщить модератору
 Re: передача в функцию ссылок, укзателей  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Anatoly Moskovsky
andron81,

newArray[i] = (*arr1)[i];



спасибо !
21 фев 20, 16:04    [22084735]     Ответить | Цитировать Сообщить модератору
Все форумы / C++ Ответить