Есть следующий код:
#include "stdio.h"
void ptr(int *ptr, int d)
{
*ptr = d;
}
void ref(int &ref, int d)
{
ref = d;
}
int main(void) {
int digit = 154;
int &a = digit;
ref(a, 999);
printf("%d - %d\n", digit, a);
ptr(&a, 1000);
printf("%d - %d\n", digit, a);
return 0;
}
Интересует следующее:
Есть такое понятие как передача по значению, работает ли это понятие когда мы передаем аргумент: как указатель, как ссылку?(Лучше объяснить как и почему)
P.S Мне почему-то кажется что когда мы передаем аргумент как указатель то создается внутренняя переменная (локальная), а значит тратится память и так каждый раз при передаче указателю. С ссылкой пока не ясно.
По сути, все варианты - передача по значению.
При f(T t)
по значению передается объект t
, для которого создается временная копия.
Очевидно, что при передаче по указателю f(T* t)
по значению передается указатель t
, для которого создается временная копия. Памяти тратится ровно столько, сколько занимает указатель.
При передаче по ссылке f(T&t)
фактически происходит передача указателя. Можно рассматривать эту передачу как передачу по указателю, просто указатель в теле функции везде разыменован, так что не приходится писать то-то типа *t = 5;
- грубо говоря, эту *
за вас добавляет компилятор. Соответственно, памяти и в этом случае тратится ровно столько, сколько занимает указатель.
Как иллюстрация - https://godbolt.org/g/TSZt1y
Если у вас есть функция, объявленная, к примеру, как
void f( T parm );
где T
- это некоторый тип, и функция вызывается с некоторым аргументом arg
, как
f( arg );
то это можно представить следующим образом
void f( /* T parm */ )
{
T parm = arg;
//...
}
То есть параметры функции - это ее локальные переменные, которые инициализируются аргументами, переданными функции при ее вызове.
Для функций из вашего примера это можно представить следующим образом
Следующее определение функции и ее вызов
void ptr(int *ptr, int d)
{
*ptr = d;
}
// ...
ptr(&a, 1000);
можно представить как
void ptr( /* int *ptr, int d */ )
{
int *ptr = &a;
int d = 1000;
*ptr = d;
}
То есть переменные ptr
и d
являются локальными переменными функции, которые после завершения работы функции прекратят свое существование.
То же самое имеет место и для данной функции и ее вызова
void ref(int &ref, int d)
{
ref = d;
}
//...
ref(a, 999);
Их можно представить следующим образом
void ref(/* int &ref, int d */)
{
int &ref = a;
int d = 999;
ref = d;
}
Поэтому если вы хотите изменить исходный аргумент, то соответствующий параметр функции следует объявлять либо как ссылку на тип объекта, передаваемого в качестве аргумента, либо как указатель на тип объекта, передаваемого в качестве аргумента.
Механизм объявления ссылки в качестве параметра функции обычно заключается в том, что выделяется память для ссылки в функции, и ссылка инициализируется аргументом, который в свою очередь передается через указатель на аргумент.
Допустим есть два обычных одномерных массива и есть функция принимающая один массивНеобходимо объединить эти два массива в один и передать...