В приведенном ниже коде выводится значение 20, и дается пояснение, что внутри fun()
q
является копией указателя p
. Поэтому, если мы изменим q
на то, чтобы указать что-то еще, тогда p
остается незатронутым. Каков механизм создания функции указателей. Почему p
не печатает 10, когда хранит адрес q
.
void fun(int *p)
{
static int q = 10;
p = &q;
}
int main()
{
int r = 20;
int *p = &r;
fun(p);
printf("%d", *p);
getchar();
return 0;
}
Поскольку функция fun
передает аргументы по значению. Если вы хотите изменить переменные вне функции, вам понадобятся указатели. Поскольку вы хотите изменить указатель int *
вне функции, вам понадобится указатель int **
:
void fun(int **p) //here
{
static int q = 10;
*p = &q;
}
int main()
{
int r = 20;
int *p = &r;
fun(&p); //and here
printf("%d", *p);
return 0;
}
В C++ вы можете использовать pass-by-reference аналогичным образом.
"если мы изменим q, чтобы указать на что-то другое" - q не указывает, это не указатель. Это целое число. Если вы имели в виду "Если мы изменим значение q", например,
q = 12
Затем происходят две вещи.
* p меняется с 10 на 12, потому что * p означает "значение в",
Наконец, "почему p не печатает 10",
Функция p в вашей основной функции отличается от p в вашей "веселой" функции. Они начинаются с того же значения, поскольку вы передаете его (fun (p)), но когда вы меняете его (p = & q), вы меняете p в забаве, а не p в основном. Таким образом, p остается указывать на & r (not & q), и поэтому * p равно 20
Существуют две разные переменные, называемые p
.
Один из них объявлен в main()
, другой в fun()
(переменные, объявленные в списке параметров, являются локальными для функции). Они не конфликтуют, потому что они являются локальными переменными в разных функциях, но это выглядит запутанным.
Обратите внимание, что будет создан тот же код, что ссылки в fun()
назывались pp
вместо p
, но вы не смущались бы думать о них той же переменной.
объясняется, что внутри fun() q является копией указателя p
Нет. p
в fun
- это копия p
в main.
Поэтому, если мы изменим q, чтобы указать что-то еще
q
не является указателем. Вы не можете указывать на что-то еще или на что-либо вообще ссылаться.
Каков механизм создания функции указателей.
Аргумент в вызове функции:
fun(p); // this p here
копируется в параметр в определении функции:
void fun(int *p) // this p here
Почему p не печатает 10, когда хранит адрес q.
Поскольку p
не сохраняет адрес q
. По крайней мере, не p
в основном, который разыменовал ценность, которую вы печатаете. Только p
в fun
указывает на q
. Но это локальная переменная функции, и вы ничего не делаете с ней.
fun()
,q
является локальным целым числом.p
- это параметр функции, который фактически игнорируется; локальная копияp
сделана так, чтобы указывать наq
, но эта информация затем не используется, потому что функция возвращается. Если вы написали (внутриfun()
)*p = q;
, тогда вы назначите 10 дляr
(и*p
) в своей функцииmain()
.