int *a;
a
представляет собой адрес, где целое число может быть сохранено. &a
- это адрес, в котором хранится a. Затем, где хранится &a
? И где хранится &(&a)
? А где хранится &(&(&a))
? Где останавливается это сохранение адресов?
int *a;
a
представляет собой адрес, где целое число может быть сохранено. &a
- это адрес, в котором хранится a. Затем, где хранится &a
? И где хранится &(&a)
? А где хранится &(&(&a))
? Где останавливается это сохранение адресов?
&a
Постоянная ссылка.
&(&a)
является незаконным.
константа внутри этой области = P – DevinB
'& a' is not действительно постоянный. Переменная может быть в стеке. Он вычисляется во время выполнения. –
Это rvalue (то есть то, что вы положили на правую сторону оператора присваивания), и, следовательно, постоянный в отношении программы. Тот факт, что он может иметь разные значения для разных прогонов, не имеет значения. –
Если вы явно не пишете &a
, он не будет храниться нигде. Если вы пишете, тогда адрес будет вычислен и сохранен либо в неназванной переменной (временном), либо в именованной переменной, которую вы пишете.
Например:
functionCall(&a); // address will be in a temporary variable used for passing the parameter
int** b = &a; // address will be stored in variable b
otherFunctionCall(&&a); // illegal, since &a is an expression operator & can't be applied to it
Даже если я не пишу & a, должно быть какое-то место, где фактически хранится? – dharm0us
@dta: Я не уверен, что понимаю ваш вопрос здесь ... 'a' хранится в стеке, как и любая другая локальная переменная. Когда вы пишете '& a', программа вычисляет адрес того, где хранится стек' a' (он уже знает указатель стека, потому что это регистр и он знает смещение в фрейме стека, потому что он скомпилирован как константа) и делает с ней что-то, что объясняется sharptooth. – rmeador
Ну, да. Вы снова путаете переменную и адрес переменной. Они обычно не равны. Переменная - это фрагмент памяти, расположенный на некотором адресе и содержащий некоторое значение. – sharptooth
& а есть адрес. Это значение, результат оператора &, примененного к a, и не «сохраняется», и не имеет адреса, поэтому & (& a) недействителен. Это как 2 + 3.
a является переменной типа «адрес int»; & a - адрес переменной a; & (& а) будет адрес адреса переменной а, что не имеет смысла
a
не является «адрес, где целое число может быть сохранено». a
- это переменная, достаточно большая, чтобы удерживать адрес целого. Единственное «целое» можно хранить непосредственно в a
это адрес целого, рассматривается как само целое:
int *a;
int b;
a = &b;
printf("a is now %x\n", (unsigned int) a);
Это правильно, что a
сам имеет адрес, который &a
, но адрес не является хранится где-то явным, во время выполнения.
На участке, вы можете быть в состоянии сохранить то, что выглядит как целое число 0:
a = 0;
Но это просто сокращенный синтаксис для «указателя NULL», то есть значение указателя гарантированно не быть адресом любого фактического объекта.
Это ответ не идеален ... но это определенно +1, поскольку я думаю, что он определенно получил наилучший шанс объяснить/ответить на исходный вопрос для искателя. – Beska
Не совсем. a
- это переменная, в которой может храниться адрес некоторого целого. &a
- адрес a
, i. е. адрес переменной a
, который может содержать адрес некоторого целого.
Очень важно: до и до тех пор, пока адрес a
не будет адресован, это неинициализированный указатель. Попытка использовать то, на что указывает, приведет к непредсказуемым результатам и, скорее всего, приведет к краху вашей программы.
У вас может быть указатель на указатель.
Ex:
void foo(int **blah)
{
int *a = *blah;
...
}
Указатель занимает память. Это всего лишь маленький контейнер, который содержит адрес чего-то. Он просто не может заняться «отсутствием пространства», потому что все на компьютере представлено каким-то образом цифрами. Просто, поскольку C/C++ сконцентрирован, int * a является просто указателем на объект и не занимает места. Это значит, что вам не нужно управлять какой-либо памятью ... он держит машину отдельно от кода.
Указатель, безусловно, занимает память. int * a; выделяет локальную переменную в стеке, которая занимает, однако, для хранения указателя на вашем компьютере требуется много байтов. – Dima
Вы можете продолжать идти вечно:
int value = 742;
int *a = &value;
void *b = &a;
void *c = &b;
void *d = &c;
Вы бы не поставить его на одной линии, не назначая его ни к чему - в этом случае было бы недействительным.
Да, но использование void обычно нахмурилось. Лучше написать int ** b, int *** c, int **** d и т. Д. – Dima
int * a; является указателем на int, называемым 'a'. & a; является различием int * a. это указывает на самого себя. это то, что вы использовали бы, чтобы указать на переменную, которую вы хотели бы передать от функции к функции. derefrence - просто причудливое слово для «получения адреса назад». & (& (& a)) не является допустимым выражением, как указано ранее. вы можете сделать указатель на указатель на указатель. Возможно, это то, о чем вы думаете. В таком случае вы бы отменили последний указатель, и компьютер должен понять, о чем вы говорите.
Чтобы ответить на вопрос «где», «сохранен»; в стеке.
пожалуйста, если я ошибаюсь ни на чем, дайте мне знать.
& a - это номер, который является rvalue: вы можете сохранить его где-нибудь, если хотите, в переменной, которую вы объявили или присвоили, типа int *.
А именно:
int a = 42;
&a; /* this does not store the address of a because you've not assigned the value to a variable */
int **aptr = &a; /* aptr is on the stack */
int **aptr2 = (int*)malloc(sizeof(int*));
aptr2 = &a; /* aptr2 is in the heap */
& (& а) не является законным синтаксис. Если вы хотите указатель на указатель на междунар:
int b = 39;
int *bptr = &b;
int **ptr2bptr = &bptr;
Вы должны создать уровни косвенности.
С выше, вы можете это сделать, если вы хотите:
printf("%d\n", *aptr);
printf("%d\n", *aptr2);
printf("%d\n", *bptr);
printf("%d\n", **ptr_to_bptr);
Производство вывод:
42
42
39
39
int *a
переменная размер указателя, так же, как int b
бы автоматический int variable.
Если эта декларация в функции, эта переменная автоматически и хранится на [stack
] (http://en.wikipedia.org/wiki/Stack_(data_structure)#Hardware_stacks) во время выполнения (простой стек декремента выделяет память для него).
Если декларация носит глобальный характер, то «a» - это просто , отображаемый в исполняемом файле .DATA
.
Все больше & признаки прилагаемая может «создать хранилище», из-за временных переменных, которые вы используете для холдем;):
b = &a; //the address in the executable's .DATA or on the stack (if `a` auto)
c = &b; //the address of `b` on the stack, independent of `a` or `&a`
d = &c; //the address of `c` on the stack, independent of `a` or `&a`
z = &(&a); //error: invalid lvalue in unary '&'
Последняя строка жалуется на то, что &
требует операнда должен быть lvalue
. То есть, что-то назначаемое - например, b
и c
. (&a)
как результат выражения, которое нигде не хранится, поэтому не является lvalue
.
int* a;
Эта строка просто объявляет указатель на целое число. У этого указателя есть ячейка памяти, в которой вы можете получить адрес использования & a. & - оператор , который возвращает адрес того, на что он запущен. Но если вы не присвоите это значение нигде, больше не возможно &.
Что касается вашего вопроса о том, где & a хранится, скорее всего, в регистре. Если вы не используете значение, оно будет немедленно отменено. (И регистры не имеют адресов памяти, поэтому вы не можете сделать & (& a))
В основе вашей проблемы, по-видимому, лежит недостаток понимания физической природы памяти и указателей. Не так, как работает код. Как я уверен, вы знаете, что физическая память состоит из большой группы соседних ячеек. Адреса этих ячеек фиксированы и жестко закодированы самим компьютером, а не программными приложениями или используемым вами языком программирования. Когда вы обратитесь к & a, вы имеете в виду физический блок памяти, который в настоящее время хранит ваше значение, которое вы сохранили в башенном компьютере. «a» - это просто имя, которое вы дали компьютеру, чтобы он точно знал, какой блок памяти должен найти значение, которое вы сохранили. Я думаю, что в значительной степени распространяется адрес памяти.
Теперь перейдем к указателям. Указатель - это еще один адрес памяти, на который ссылается компьютер. У него есть любое имя, которое вы ему даете. В этом случае его следует называть чем-то другим, кроме того же имени, которое вы указали на свое первое значение. Позволяет называть его «b». Основываясь на том, как вы это объявили. b может хранить только один тип данных .... другое место памяти .... поэтому, когда я говорю: b = & a Я говорю, что адрес памяти 'b' (который предназначен только для сохранить адреса памяти), заключается в том, чтобы удерживать адрес памяти 'a'. Между тем на другой стороне города адрес памяти «a» имеет целое число, сохраненное в нем.
Надеюсь, что это не запуталось, я постарался не получить здесь всех техно-болтовней. Если ты все еще смущен. Повторите попытку, в следующий раз я объясню код.
-UBcse
В C, переменная x
может выступать в качестве значения (на правой стороне =, где он называется Rvalue), или он может выступать в качестве контейнера для значения (в левой части =, где это называется lvalue). Вы можете взять адрес x
, так как вы можете взять адрес любой lvalue — это дает вам указатель на контейнер. Но поскольку указатель представляет собой rvalue, а не контейнер, вы никогда не сможете взять &(&x)
. Фактически для любого номера l
, &l
является законным, но &(&l)
никогда не является законным.
Если вы действительно ищете, как указываются указатели, ознакомьтесь с этим ответом на: http://stackoverflow.com/questions/991075/does-a-pointer-also-have-any-address-or-memory-allocation/991152#991152 –
Здесь также: http://stackoverflow.com/questions/96285/in- ci-can not-grasp-pointers-and-classes/98525 # 98525 –