![](/img/trans.png)
[英]Why don't pointers have same address as the variable they are pointing to?
[英]Why do variable pointers contain the address of the same data type?
指針聲明的一般語法: data-type *pointer_name;
指針是一個變量,其值是另一個變量的地址,即存儲位置的直接地址。 像任何變量或常量一樣,必須先聲明一個指針,然后才能使用它存儲任何變量地址。 指針的數據類型必須與指針所指向的變量相同。
為什么指針變量應包含相同數據類型的變量的地址很重要?
由於指針與另一個變量的值無關,為什么整數指針不能具有float數據類型變量的地址?
正確形式:
整數= 10;
int * ptr =&a;
錯誤,類型不匹配
浮動
int * ptr; ptr =&a;
在回答之前,請允許我問您,如果有效,您將如何使用此類指針?
假設您有(在函數內)
float a;
int *ptr; ptr = &a;
*p = 1;
++*p;
return *p;
在這種情況下,根本沒有理由不只使用int
變量(如果您想要的是int
。
假設您有(在函數內)
float a;
int *ptr; ptr = &a;
a = 3.14;
++*p;
return a;
在這種對象別名中,可以使用,但允許這樣的構造對編譯器來說是一個痛苦。 編譯器可以自由假設,有些甚至可以假設*p
的修改對a
的值沒有影響,因此仍然返回3.14未經修改;
如果您要尋找后一種情況,則可以使用union
,這不僅使其他讀者更清楚代碼,而且使編譯器更清晰代碼:
union {
float f;
int i;
} u;
u.f = 3.14;
++u.i;
return u.f;
因此,回答:這是為了防止您用腳射擊自己。 這是不允許的,因為這樣的指針不可能有用。 它可能有用的一種情況實際上是它不起作用的情況,還有另一種語言構造可以處理它並正確處理它。
因為當您增加指針
ptr++;
它將指向一個地址,該地址乘以數據類型的大小。 如果你這樣做
ptr+=2;
並且數據類型占用4個字節,如果指針被聲明為
float *ptr;
指針將增加8個字節的位置。
這是一項安全功能。 一種類型的指針指向另一種變量是災難的根源。 它幾乎沒有合法目的,並且您使用它進行的幾乎任何操作都是危險的,尤其是在類型大小不同的情況下。
您可以通過強制轉換來覆蓋此功能。 如果這樣做,您將無法再聲明自己不知道自己在做危險的事情。
取消指針的引用也很簡單。
東西= *指針;
取消引用指針后應讀取多少數據? 編譯器必須知道數據類型,才能對數據執行操作,例如提取,添加等。
這是可能的指針指向任何數據類型:這正是void
指針的。 您可以使用void *
指向任何數據類型1 ,然后可以返回原始指針。
float f = 1.0f;
int i = 12;
void *p = &f;
p = &i;
當然,如果不先將void
指針強制轉換回正確的指針類型,就無法取消引用它。 您需要確保指針類型正確。
// In C, this is valid: implicit conversions to void * and back.
float f = 1.0f;
void *p = &f;
float *fp = p;
printf("*fp = %f\n", *fp);
// In C++, you have to use a cast:
float *fp = static_cast<float *>(p);
無效指針具有局限性:您不能取消引用它們,也不能執行任何指針算術。
1 :函數指針不應強制轉換為void *
。
讓我們通過一個例子來理解它。
int main()
{
char i = 8;
int *ptr = &i;
printf("Value of i = %d", *ptr);
return 0;
}
回答:它會打印一些垃圾,因為它在內存中取消引用了4個字節。 所以如果你做char *ptr = &i;
,它將取消引用1個字節,依此類推。。它將給出正確的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.