Например этот код:
#include <iostream>
using namespace std;
void foo(int* x){ cout << "X = " << *x << endl;}
int main()
{
int value = 5;
int *p = &value;
foo(p);
foo(&value);
return 0;
}
В первом вызове функции foo
копия указателя p (x) фактически создается внутри функции и удаляется, как только функция завершается, верно? Во втором звонке foo
адрес значения переменной берется, и указатель x создается с этим адресом и удаляется, как только функция завершается, верно? Какой из этих вызовов дешевле с точки зрения потребления стековой памяти? Или это одно и то же?
Они оба похожи. Первый выглядит дороже, потому что вы создаете указатель дважды, один раз как локальная переменная (внутри main
) и снова в качестве параметра функции (передается в foo
), однако фаза «оптимизации» компилятора, вероятно, превратит первое во второе (при условии, что единственное, что вы делаете с p
это передать, и вы не будете использовать его позже в main
).
Они практически идентичны. Разница лишь в том, что у вас есть объект указатель p
в стеке вызовов в main
Но если вы будете беспокоиться об этом, у вас есть проблемы. 🙂
В первом вызове вы передаете переменную, содержащую адрес из value
,
Во втором вы передаете адрес из value
непосредственно.
Обратите внимание, что оператор присваивания говорит, что оба p
а также &value
одинаковы, так что вы должны иметь возможность передать любой из них, как вы уже доказали.
У указателей есть значения, которые можно копировать, как и все остальное. Oни
имеют значение-семантику.
void foo(int* t);
принимает указатель по значению Это создаст копию указателя
аргумент и использовать его внутри своего тела.
int value = 23;
int *p = &value; // &value takes the address of value and use it to copy initialize p
foo(p); // copy the value of the pointer inside foo
foo(&value); // do the same but don't create a temporary