为什么指针与它们指向的变量的地址不同?

Why don't pointers have same address as the variable they are pointing to?

我是 C++ 的初学者(并且不了解 C ,来自 Java 和 Python 背景)。

我正在学习指针和运行我从我的自我教程文件中分享的以下代码:

#include<iostream>
using namespace std;

int main() {
        //What is a pointer:-
        // A datatype that holds address of a variable in other datatype
        
        int a=3;
        int* b = &a; //CREATE A POINTER THAT POINTS TO A
                     // '&'STANDS FOR ADDRESS OF OPERATOR
                     // '*' IS CALLED DEREFERNCING OPERATOR
        cout<< b<<endl; //prints address of a
        cout<<&a<<endl; //does the same stuff
        //retrieving stored at a particular address
        // '*' GIVES VALUE AT THE ADDRESS STORED IN POINTER
        cout<<*b<<endl;
        cout<<*&a<<endl;
        //pointer to a pointer
        int** c = &b; // pointer to another pointer b
        cout<<"The address of b is"<<c<<endl;
        cout<<"The address of b is"<<&b<<endl;
        cout<<"The value at address c is"<<*c<<endl;
        cout<<"The value at address value stored in c is "<< **c<<endl;
        return 0;
    }

return给我以下输出:-

0x94ac7ff7d4
0x94ac7ff7d4
3
3
The address of b is 0x94ac7ff7c8
The address of b is 0x94ac7ff7c8
The value at address c is 0x94ac7ff7d4
The value at address value stored in c is 3

引起好奇的是输出的最后四行 我们看到:-
c 指向 b

b 指向 a

它们本身不是变量那么为什么它们 return 不是同一个地址呢? 这是否意味着对同一个变量使用多个指针会占用系统资源从而导致糟糕的设计?

如果你只写 &a 那么它不是一个变量,但是一旦你声明了一个整数,它就变成了名称为 b 的变量,它恰好存储了另一个地址变量。

声明为指针的变量是指针类型的对象。他们占据了自己的记忆。

所以这些声明

int a=3;
int* b = &a;
int** c = &b;

声明三个存储不同值的不同变量。第一个变量的类型为 int 并存储值 3。第二个变量的类型为 int * 并存储第一个变量的地址。第三个变量的类型为 int ** 并存储第二个变量的地址。

如果你有这样的声明

T a;

其中 T 是某种类型说明符,则指向此变量的指针声明如下所示

T *p = &a;

其中 T 例如可以是 int *。在这种情况下,您将拥有声明

int * *p = &a;

或者省略多余的空格看起来像

int **p = &a;

根据您“不是变量”的印象考虑以下代码。

int a = 3;
int b = 4;
int *p = &a;
std::cout << p << " -> " *p << std::endl;
p = &b;
std::cout << p << " -> " *p << std::endl;

一图胜千言

   +----------------+
a: |              3 |               94ac7ff7d4
   +----------------+
    ^                              
    |
    `-------------.
                  |
   +--------------|-+
b: | 0x94ac7ff7d4 * |               94ac7ff7d8
   +----------------+
    ^
    |
    `-------------.
                  |
   +--------------|-+
c: | 0x94ac7ff7d8 * |               94ac7ff7dc
   +----------------+

我认为变量 a 是一个可以容纳整数的小盒子。在 C 中,我们通过标识符 a 知道它,但实际上,在机器级别,编译器已将其分配到地址 0x94ac7ff7d4.

类似地,b 是一个小盒子,可以容纳一个指向整数的指针,通常实现为存储整数的地址(数字)。我们通过标识符 b 知道它,但实际上,编译器已将其分配到地址 0x94ac7ff7d8.

最后,c是一个盒子,它可以容纳一个指向整数的指针,它又被实现为存储指针的地址。我们通过标识符 c 知道它,虽然您没有这么说,但我猜编译器已将它分配到地址 0x94ac7ff7dc.

对于任何变量,& 为您提供存储变量的地址——这是您可以存储在指针变量中的那种值。

对于指针值,* 为您提供指针指向的值。 (对于指向指针的指针,** 为您提供指针指向、指向等的指针的值)

指针和其他对象一样是一个对象。它有一个类型和一个值。通常一个指针保存另一个对象的地址,尽管这并没有使它们像你想象的那么特殊。

考虑一下:

int a = 0;
int b = 0;
int* p = &a;
p = &b;

int* p = &a; 初始化 p 指向 aps 的值是a 的地址。下一行使 p 指向 b。现在 ps 的值是 b 的地址。指针值需要存储在某处,就像 int a = 0;0 需要存储在某处一样。

在内存中,int aint* p 的值只是位和字节。只有解释为“一个整数”或“指向一个整数”才使指针变得特殊。

请记住 C 是一种非常低级的语言。很多东西都是字面上存在的,没有花哨的处理。

int *b;

b 是一个变量,就像任何值一样。它存在于地址 0x94ac7ff7c8 并包含值 0x94ac7ff7d4;

int **c = &b;

c也是一个变量。它存在于内存中(在程序未评估的地址)它包含值 0x94ac7ff7c8,与 b.

的地址的值相同

不像php的引用,C的指针不会自动指向'real'变量。 执行此操作时,您实际上所做的就是为 c 赋值,因为这就是 = 运算符所做的。

c = 0x94ac7ff7c8;

因此,c 和 b 包含不同的值。

当评估“**c”时,您问的是:

“地址 c 的值是多少?0x94ac7ff7c8。好的,那么地址 0x94ac7ff7c8 的值是多少?”这个问题的答案是 **c

请注意,以下几行有两种不同的含义:

int **c = x;
**c = x;

首先,您要声明双指针类型。星号属于表达式 int **。这里 x 必须是类型 int **

在第二个中,您要取消引用 c 两次。星号属于表达式 **c,如 *(*(c))。这里 x 必须是类型 int

这种区别不会造成歧义,因为在声明指针时不可能取消引用它。它没有价值,所以没有地址可以获取。

Why don't pointers have same address as the variable they are pointing to?

指针与指针指向的对象不同(除非指针指向自身)。具有重叠存储持续时间的两个不同对象通常不能存储在同一地址中。

They are not variables themselves

这是一个错误的假设。 bc 变量本身。

Does that mean using multiple pointers for same variable can take up system resources

大多数对象都可能消耗内存。指针对象也不例外。

thus resulting in bad design?

没有办法从前提下得出这样的结论。有时很多指点是有益的。

列表项

变量是计算机主内存 (RAM) 中用于存储数据的内存位置。 指针是计算机主内存 (RAM) 中的一个内存位置,用于存储变量的地址。 指针与它们指向的变量不具有相同的地址,因为指针也是一种变量,具有不同的和自己的地址。