簡體   English   中英

c指針指向的數組的打印地址

[英]c printing address of an array pointed to by a pointer

在下面的代碼中, str是一個指針,用於存儲數組Goodbye的地址。 數組Goodbye的地址開始於4196004 ,指針*str2值為-1226226648 我的問題是,有沒有一種方法可以使用指針*str2打印數組Goodbye地址?

我嘗試了這一行printf("%d %d %s\\n", *str2, str2, str2); 取消引用str2並輸出71 ,它是H ascii,但是我將如何打印地址4196004

int main(int argc, char **argv) {

char str1[] = "Hello";
char *str2 = "Goodbye";

printf("%d %d %s\n", &str1, str1, str1);
printf("%p %d %s\n", &str2, str2, str2);

}

Output: 
-1226226640 -1226226640 Hello
-1226226648 4196004 Goodbye

您的代碼調用了Undefined Behavior,因為您嘗試不使用%p來打印地址

printf()提到:

p指針地址

並且不要像您應該的那樣投向void

因此,改為這樣做:

printf("%p %p %s\n", (void*)&str1, (void*)str1, str1);
printf("%p %p %s\n", (void*)&str2, (void*)str2, str2);

可能的輸出:

0x7ffddaf7e67a 0x7ffddaf7e67a Hello
0x7ffddaf7e670 0x4005c4 Goodbye

關於str2我們可以區分“的地址到指針str2指向”,這是在字符串文字的地址Goodbye將駐留(例如0x10007bf04從“在該指針中的地址) str2存儲”,它是可變的地址(例如0x7fff5fbff710 ),其中存儲了地址值0x10007bf04

int main(int argc, char **argv) {

    char str1[] = "Hello";
    char *str2 = "Goodbye";

    printf("%p %p %s\n", (void*)&str1[0], (void*)str1, str1);
    printf("%p %p %s\n", (void*)&str2, (void*)str2, str2);

}

與指針相反, *str2表示字符值,因為它取消引用指針str2 然后,獲取“ * str2的地址”將是str2指向的字符串文字的第一個字符的地址。 您可以將其寫為&(*str2)&str2[0] ,但都可以轉換為str2

請注意,使用格式"%d"打印指針會調用未定義的行為。

首先修復未定義的行為-將指針轉換為void* ,然后使用%p進行打印:

printf("%p %p %s\n", (void*)&str1, (void*)str1, str1);
printf("%p %p %s\n", (void*)&str2, (void*)str2, str2);

這將產生以下輸出

0x7ffe95676bf0 0x7ffe95676bf0 Hello
0x7ffe95676be8 0x2b4dca5eb7d4 Goodbye

我們來看一下為什么str1str2打印行之間會有差異。

原因是str1是一個數組,而str2是一個指針。 當您使用操作符&指向數組的指針時,會產生一個指向數組的初始元素的指針; 當您將數組隱式轉換為指針時,還會獲得一個指向數組初始元素的指針。 因此, &str1str1%p兩個打印輸出都產生相同的值0x7ffe95676bf0

另一方面, str2是一個指針。 它指向某個東西(字符串文字"Goodbye" ),但是它也有自己的地址。 當打印不帶& str2 ,您將獲得指針的值,即字符串文字"Goodbye"的位置。 但是,在打印&str2時,將獲得一個指向指針str2指針,這是str2的位置。 這與"Goodbye"的位置不同,因此打印輸出也不同。

如果您以str2的地址開頭,即

char *str2 = "Goodbye";
char **ptrStr2 = &str2;

您可以通過取消引用來獲取"Goodbye"的位置,即

printf("%p %s\n", (void*)*ptrStr2, *ptrStr2);

演示。

對於初學者,您應該在函數printf使用正確的轉換說明符。 否則,該函數的行為是不確定的。

所以這些電話

printf("%d %d %s\n", &str1, str1, str1);
printf("%p %d %s\n", &str2, str2, str2);

是錯誤的,因為在轉換說明符%d使用了指針。

我的問題是,有沒有一種方法可以使用指針* str2打印數組再見的地址?

實際上,對應於字符串文字"Goodbye"的數組的地址與字符串文字的第一個字符的地址相同。

char *str2 = "Goodbye";

但是,您無法使用指針str2獲得指向字符串文字的指針。

問題是什么?

指針str2知道它是指向char類型的單個對象還是指向某個數組的第一個字符。 它不保留此類信息。

考慮到與字符串文字"Goodbye"相對應的數組的類型為char[8] 因此,指向該數組的指針應具有char ( * )[8]

你可以寫例如

char ( *str2 )[8] = &"Goodbye";

在這種情況下,指針str2實際上將具有數組的地址。 否則,將具有示例中定義的指針

char *str2 = "Goodbye";

您無法獲得數組的地址,因為如前所述,指針對數組及其大小一無所知。

另一方面,字符串文字的第一個字符的地址值等於指向字符串文字的指針的值。 那就是要考慮第一個宣言

char str1[] = "Hello";

然后,盡管表達式的類型不同,但表達式str1&str1將產生相同的值。 第一個具有char *類型(如果在上下文中將數組指示符隱式轉換為指向其第一個元素的指針時使用該表達式)。 第二個具有char ( * )[6] 但是兩個值將相等。

從輸出看來(假設您使用了正確的轉換說明符)

-1226226640 -1226226640 Hello

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM