Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / передача в функцию ссылок, укзателей / 14 сообщений из 14, страница 1 из 1
20.02.2020, 16:51
    #39929038
andron81
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
Добрый день .

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

Код: plaintext
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.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
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 в телах обоих функций . в чём их разница.
могу предполагать , что и в одной и в другой процедуре создается локальные копии которые обе имеют связь с динамическим массивом.
затем дойдя до строчки :
Код: plaintext
1.
delete[]arr1;



потом мы уничтожаем объекты созданные
int* arr = new int[SIZE];
а потом после этого
arr1 = newArray;
ничего не работает в push_backptr (хотя работает в похожей push_backptr :) )
и работает в в push_backref
...
Рейтинг: 0 / 0
20.02.2020, 17:46
    #39929077
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
andron81,

Код: plaintext
1.
2.
3.
4.
5.
6.
void push_backptr(int **arr1, int& size, const int value)
{
	...
	delete[] *arr1;
	*arr1 = newArray;
}
...
Рейтинг: 0 / 0
20.02.2020, 18:01
    #39929091
andron81
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
Anatoly Moskovsky
andron81,

Код: plaintext
1.
2.
3.
4.
5.
6.
void push_backptr(int **arr1, int& size, const int value)
{
	...
	delete[] *arr1;
	*arr1 = newArray;
}



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

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

Самое главное я не понимае чем физически являюся эти локальные копии в функциях
...
Рейтинг: 0 / 0
20.02.2020, 18:24
    #39929112
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
andron81
А прокомментировать? :))

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

PS Аналог ссылки на указатель это указатель на указатель
...
Рейтинг: 0 / 0
20.02.2020, 18:48
    #39929127
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
andron81Мне что это ** arr, что это *& arr одинакого выносит мозг:))

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

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

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

Тогда тебе следует изучить ассебмлер и читать результат компиляции (ключик --save-temps
рулит).
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
20.02.2020, 18:54
    #39929134
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
andron81,

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
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;
...
Рейтинг: 0 / 0
20.02.2020, 19:00
    #39929140
andron81
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
Dimitry Sibiryakov

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

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



Дайте название книги и автора, пожалуйста:)
...
Рейтинг: 0 / 0
20.02.2020, 19:05
    #39929143
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
andron81Дайте название книги и автора, пожалуйста:)

Чтоб я ещё помнил такие мелочи... Но рекомендую
https://en.cppreference.com/w/cpp/language/basic_concepts
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
20.02.2020, 19:05
    #39929144
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
andron81
Дайте название книги и автора, пожалуйста:)

Классика https://www.ozon.ru/context/detail/id/150133610/
...
Рейтинг: 0 / 0
20.02.2020, 19:09
    #39929146
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
Да и гугль не подводит:
https://www.codeproject.com/Articles/7042/How-to-interpret-complex-C-C-declarations#right_left_rule
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
20.02.2020, 19:14
    #39929149
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
Dimitry Sibiryakov, твои ссылки не для чайников, не пугай ТС`а ))
...
Рейтинг: 0 / 0
21.02.2020, 15:14
    #39929528
andron81
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
Anatoly Moskovsky
andron81,

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
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];

Код: plaintext
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.
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);
	
}
...
Рейтинг: 0 / 0
21.02.2020, 15:47
    #39929551
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
andron81,

newArray[i] = (*arr1)[i];
...
Рейтинг: 0 / 0
21.02.2020, 16:04
    #39929566
andron81
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
передача в функцию ссылок, укзателей
Anatoly Moskovsky
andron81,

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



спасибо !
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / передача в функцию ссылок, укзателей / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]