繁体   English   中英

关于 printf 的 output 处理指向数组的指针的问题

[英]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] - 这是b0th个元素的地址。
   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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM