我的问题是:如果指针变量与其值具有相同的地址,它是否真的指向自身?
例如 - 在下面的代码中,是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);
}
Run Code Online (Sandbox Code Playgroud)
如果a
不是指向自身的指针,则同样的问题再次出现:指针可以指向自身吗?
另外,自指向指针有用吗?
小智 38
void* p = &p;
Run Code Online (Sandbox Code Playgroud)
它并不是非常有用,但是指向自身的结构在长度为1的循环列表中很有用:
typedef struct A {
struct A* next;
} A;
A a = { &a };
Run Code Online (Sandbox Code Playgroud)
根据你的确切例子,我相信你的意思是:
int* a;
int b = (int)&a;
a = (int*)b;
// which can be simplified to:
int* a = (int*)&a;
Run Code Online (Sandbox Code Playgroud)
Cam*_*Cam 34
你实际上在做什么并没有指针指向自己.您正在使用为指针分配的内存空间来存储指针的位置.指向int的指针指向int - 从不指向int的其他指针,包括它自身.
例如,假设您创建了一个指针a
:
int * a;
Run Code Online (Sandbox Code Playgroud)
它在内存中占有一席之地:
4 a (5) 6
[....][00000000][....]
Run Code Online (Sandbox Code Playgroud)
在这个简单的例子中,假设a位于内存位置'5'.
如果你这样做:
a = (int*)&a;
Run Code Online (Sandbox Code Playgroud)
......会发生以下情况:
4 a (5) 6
[....][00000005][....]
Run Code Online (Sandbox Code Playgroud)
这里发生的a
是指向它认为是位置5的整数.这也恰好&a
是指向的内存位置,但是在a
指向的内容中,它现在指向位置处的整数5 - 那个整数是5.
例如,这两个都可以工作:
cout<<(int)a;//outputs 5
cout<<*a;//Outputs the integer at memory location 5 - which is 5.
Run Code Online (Sandbox Code Playgroud)
如果你想创建一个指向a的指针,你绝对可以 - 通过以下方式之一:
int **b = (int**)a;
Run Code Online (Sandbox Code Playgroud)
要么
int ** b = &a;
Run Code Online (Sandbox Code Playgroud)
但要意识到这a
不是指向自身的指针是非常重要的.它是指向它存储位置的整数的指针- 恰好与它自己的位置相同.
为了进一步展示(通过一个更简单的例子)正在发生的事情,类似的事情可能发生在int
.也就是说,您可以存储内部的内存位置int
:
int a=999;
Run Code Online (Sandbox Code Playgroud)
a
现在在内存中有一个位置,其值为999(我们假装它已被放置在内存位置'46'):
45 a (46) 47
[....][00000999][....]
Run Code Online (Sandbox Code Playgroud)
它在位置'46' - 如果我们想要,我们可以将这个数字存储为整数a
:
a=(int)&a;
45 a (46) 47
[....][00000046][....]
Run Code Online (Sandbox Code Playgroud)
现在a
等于&a
值,但不是类型 - a
只是一个整数,它现在并不神奇,因为我们用它来存储自己的内存位置.
好吧,首先我要更改代码:
int **a;
a = (int **)&a; // otherwise you get a warning, since &a is int ***
Run Code Online (Sandbox Code Playgroud)
我不确定你为什么会这样做,但是这是允许的.
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 **
Run Code Online (Sandbox Code Playgroud)
他们应该打印出同样的东西.
The address of a is 0x7fffe211d078
a holds the address 0x7fffe211d078
The value at 0x7fffe211d078 is 0x7fffe211d078
Run Code Online (Sandbox Code Playgroud)
请注意,这不是一个好主意,因为第一次a = (int **)&a
强制a
转换是强制持有它不应该持有的值的黑客.你声明它是一个int **
但是试着强迫它int ***
进入它.从技术上讲,大小是相同的,但通常不这样做,因为人们希望a int *
保存可以用作的东西的地址int
,等等.