[英]Variable created on the heap, 2 pointers pointing to same variable have different addresses?
[英]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;
}
這給了我以下輸出:-
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
的值是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 = 3;
int b = 4;
int *p = &a;
std::cout << p << " -> " *p << std::endl;
p = &b;
std::cout << p << " -> " *p << std::endl;
指針和其他對象一樣是一個對象。 它有一個類型和一個值。 通常,指針保存另一個對象的地址,盡管這並不像您想象的那樣特殊。
考慮一下:
int a = 0;
int b = 0;
int* p = &a;
p = &b;
int* p = &a;
將p
初始化為指向a
。 p
價值是的地址a
。 下一行使p
指向b
。 現在p
值是b
的地址。 指針值需要存儲在某個地方,就像int a = 0;
值0
需要存儲在某處。
在內存中, int a
和int* p
的值只是位和字節。 只有將指針解釋為“整數”或“指向整數”才能使指針變得特殊。
為什么指針的地址與它們指向的變量的地址不同?
指針是與指針指向的對象不同的對象(除非指針指向自身)。 具有重疊存儲持續時間的兩個不同對象通常不能存儲在同一地址中。
它們本身不是變量
這是一個錯誤的假設。 b
和c
本身就是變量。
這是否意味着對同一個變量使用多個指針會占用系統資源
大多數對象可能會消耗內存。 指針對象也不例外。
從而導致糟糕的設計?
沒有辦法從前提下得出這樣的結論。 有時很多指針是有益的。
項目清單
變量是計算機主內存 (RAM) 中用於存儲數據的內存位置。 指針是計算機主內存(RAM)中的內存位置,用於存儲變量的地址。 指針與它們所指向的變量的地址不同,因為指針也是一種變量,具有不同的和自己的地址。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.