[英]Question regarding output of printf in handling pointer to array
我正在比較各種printf
以更好地理解int *
和int (*)[]
之間的區別以及我如何可視化各種地址和值。
在下面的程序中,我寫了一件讓我煩惱的事情:
#include <stdio.h>
int main() {
int a[3] = {1,2,3};
int *p = a;
printf("address of a: %p\n", &a);
printf("\naddress of a[0]: %p\n", &a[0]);
printf("\nvalue of p: %p\n", p);
printf("\nvalue of *p: %d\n", *p);
printf("\nvalue of a[1]: %d\n", *(p + 1));
puts("\n\n-------------------\n\n");
int b[3] = {1,2,3};
int (*q)[3] = &b;
printf("address of b: %p\n", &b);
printf("\naddress of b[0]: %p\n", &b[0]);
printf("\nvalue of q: %p\n", q);
printf("\nvalue of *q: %p\n", *q);
}
在第一部分中p
作為一個指針,將a[0]
的地址作為值保存,因此*p
保存為值1
(用 %d 打印)。
但是,在第二部分中, q
似乎與*q
保持相同的值(在這種情況下我使用 %p),因此我需要使用**q
來打印b[0]
。
怎么來的?
指針q
指向一個由 3 個整數組成的數組。 你可以像這樣可視化它:
q -----> |b = {1,2,3}|
// q points to the whole array.
// note how it doesn't point to a specific element.
您的打印語句細分:
&b
- 這是b
的基地址。|b = {1,2,3}| // address of whole array
&b[0]
- 這是b
的0th
個元素的地址。 b = {1,2,3}
^
// address of b[0]
q
- 這指向b
的基地址,並保持與&b
相同的值。q -----> |b = {1,2,3}| // address of whole array
*q
- 這將產生b
的第一個元素的地址,在您的情況下,這是b[0]
的地址。 b = {1,2,3}
*q ---^
關於你的問題:
使用q
您必須取消引用兩次( **q
),因為:
q
指向b
的基地址*q
),它將產生b[0]
的地址。**q
),我們將獲得b[0]
中的值。這是一個可視化,可以幫助您了解它是如何工作的。
- q -----> |b = {1,2,3}| // points to base address of b
- *q ------------^ // points to address of b[0]
- **q -----------^ // value of b[0]
int*
這樣的普通指針時,你會得到一個int
類型的項目。int (*q)[3]
這樣的數組指針時,您會得到一個int [3]
類型的數組。 現在,每當您在表達式中使用數組時(在大多數情況下),它都會衰減為指向其第一個元素的指針。 所以*q
給你一個數組int [3]
然后立即衰減為指向第一個元素的指針,類型int*
。 這就是您要打印的指針。 我們可以通過執行以下代碼片段來證明是這種情況:
_Generic(*q,
int*: puts("we ended up with an int*"),
int(*)[3]: puts("this wont get printed") );
為了打印該指針指向的值,您需要另一個級別的取消引用: (*q)[0]
或**q
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.