Указатель может когда-либо указывать на себя?

Мой вопрос: Если переменная указателя имеет тот же адрес как свое значение, это действительно указывает на себя?

Например - в следующей части кода, a указатель на себя?

#include<stdio.h>

int main(){
   int* a;
   int b = (int)&a;
   a = b;
   printf("address of a = %d\n", &a);
   printf("  value of a = %d\n", a);
}

Если a не указатель на себя, затем тот же вопрос позирует снова: указатель может указать на себя?
Кроме того, как сам указывающий полезный указатель?

39
задан JL2210 2 May 2019 в 14:10
поделиться

7 ответов

То, что вы на самом деле делаете, не , когда указатель указывает на себя. Вы используете пространство памяти, выделенное для указателя, для хранения местоположения указателя . Указатель на int указывает на целые числа, а не на другие указатели на целые числа, включая самого себя.

Например, предположим, что вы создали указатель a :

int * a;

Он получает свое собственное место в памяти:

   4     a (5)    6
[....][00000000][....]

В этом простом примере предположим, что a находится в ячейке памяти «5».

Если бы вы сделали это:

a = (int*)&a;

... произошло бы следующее:

   4     a (5)    6
[....][00000005][....]

Здесь происходит то, что указывает на то, что, по его мнению, является целым числом в позиции 5. Это также оказывается той же ячейкой памяти, на которую указывает & a , но в контексте того, на что указывает a , теперь он указывает на целое число в позиции 5 - и это целое число равно 5.

Например, оба из них будут работать:

cout<<(int)a;//outputs 5
cout<<*a;//Outputs the integer at memory location 5 - which is 5.

Если вы хотите создать указатель на a, вы определенно сможете - любым из этих способов:

int **b = (int**)a;

или

int ** b = &a;



Но очень важно понимать что не является указателем на самого себя. Это указатель на целое число в том месте, где он хранит - которое просто совпадает с его собственным местоположением.


Чтобы еще больше показать (на еще более простом примере), что происходит дальше нечто подобное может произойти с int .То есть вы можете сохранить в себе место в памяти int :

int a=999;

a теперь имеет место в памяти и имеет значение 999 (мы представим, что оно было помещено в ячейка памяти «46»):

  45     a (46)   47
[....][00000999][....]

Она находится в ячейке «46» - если бы мы хотели, мы могли бы сохранить это число как целое в пределах a :

a=(int)&a;

  45     a (46)   47
[....][00000046][....]

, а теперь a равно & a по значению, но не по типу - a является просто целым числом, теперь оно не указывает на себя волшебным образом только потому, что мы использовал его для хранения собственной ячейки памяти.

34
ответ дан 27 November 2019 в 02:15
поделиться
void* p = &p;

Это не очень полезно, но структуры, указывающие на самих себя, полезны в круговых списках длиной 1:

typedef struct A {
  struct A* next;
} A;

A a = { &a };

В вашем точном примере, я полагаю, вы имели в виду:

int* a;
int b = (int)&a;
a = (int*)b;

// which can be simplified to:
int* a = (int*)&a;
38
ответ дан 27 November 2019 в 02:15
поделиться

Разыменование указателя приводит к значению его типа значения (например, разыменование int * дает вам int , тип значения int * s). Чтобы переменная указывала на указатель, ее тип значения должен быть int * , что не относится к int * , как было указано ранее. Итак, чтобы указатель указывал на себя, нужно было бы выполнить какое-то преобразование, чтобы получить его компилятором:

int* a;
a = reinterpret_cast<int*>(&a);

Для разыменования a тогда у вас будет int , значение которого совпадает с адресом, по которому находится a (усечение по модулю адреса для соответствия типу), но это по-прежнему int , а не int * , что потребует еще одного приведения.

Указатель на указатель часто называют дескриптором , который имеет другой тип ( int ** ), чем указатель ( int * ) . (Обратите внимание, что дескриптор int ** имеет тип значения int * .)

3
ответ дан 27 November 2019 в 02:15
поделиться

Да и нет, потому что тип указателя почти так же важен, как и значение указателя.

Да, указатель может содержать позицию указателя на самого себя; даже long может содержать позицию указателя на себя. (Инты обычно могут, но я не знаю, везде ли это гарантировано.)

Однако не существует типа, представляющего эти отношения. Если у вас есть указатель, указывающий на самого себя, при разыменовании у вас фактически будет другой тип. Итак:

void *p = &p;
// *p is illegal, even though you probably wanted it to equal 'p'
if( *p != p ) {
    printf("Something's wrong");
}

int *i = (int*)&i;
// The following statement is still illegal
if( *i == i ) {
    printf("The universe works!");
}

Я бы сказал, что ответ - «нет», потому что это не сработает, если вы не собираетесь злоупотреблять системой типов. Я думаю, это признак того, что вы делаете что-то не так (хотя иногда это, безусловно, необходимо).

4
ответ дан 27 November 2019 в 02:15
поделиться

Да, можно указывать на себя.

int* a;
a = &a;

Но не иметь никакого применения, по крайней мере, явно, как это.

0
ответ дан 27 November 2019 в 02:15
поделиться

Ну, сначала я бы изменил код примерно так:

int **a;
a = (int **)&a;  // otherwise you get a warning, since &a is int ***

Я не уверен, зачем вы это делаете, но это разрешено.

printf("The address of a is %p\n", &a);
printf("a holds the address %p\n", a);
printf("The value at %p is %p\n", a, *a); // the *a is why we made a an int **

Они должны распечатать то же самое.

The address of a is 0x7fffe211d078
a holds the address 0x7fffe211d078
The value at 0x7fffe211d078 is 0x7fffe211d078

Обратите внимание, что это не очень хорошая идея, поскольку самое первое приведение a = (int **) & a - это попытка заставить a хранить значение, которого не должно быть. не держу. Вы объявляете его int ** , но пытаетесь принудительно вставить в него int *** . Технически размеры одинаковы, но в целом этого не делают, потому что люди ожидают, что int * содержит адрес чего-то, что можно использовать как int и т. Д. .

6
ответ дан 27 November 2019 в 02:15
поделиться

Адрес памяти в FFFFFFFF может хранить значение FFFFFFFF

16
ответ дан 27 November 2019 в 02:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: