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



我是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;
}

这给我返回了以下输出:-

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

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

一张图片胜过千言万语。

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

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

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

最后,c是一个框,可以保存指向整数的指针,该指针再次实现为存储指针的地址。 我们通过标识符c知道它,虽然你没有这么说,但我猜编译器已经将其分配给地址0x94ac7ff7dc.

对于任何变量,&都会为您提供存储变量的地址 - 这是您可以存储在指针变量中的值类型。

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

请记住,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

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

如果你只写&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 = 0;
int b = 0;
int* p = &a;
p = &b;

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

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

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

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

它们本身不是变量

这是一个不正确的假设。bc本身就是变量。

这是否意味着对同一变量使用多个指针会占用系统资源

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

从而导致设计不佳?

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

根据"非变量"的印象考虑以下代码。

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

列表项

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

相关内容

  • 没有找到相关文章

最新更新