为什么我可以在其他地方同时定义指针时使用它?

Why can I use a pointer while it's being defined elsewhere at the same time?

假设我有这样一个 struct

typedef struct {
    char* author;
    uint32_t isbn;
} Book;

int
main( int arg_c; char* arg_v[] ) {
    Book* b = malloc( sizeof *b );
    char* author = "Miller";

    //[...]

    free(b);
    return 0;
}

现在第 8 行让我有点困惑:Book* b = malloc( sizeof *b ); 在这里,我在等号左侧创建了一个类型为 Book 的指针 b,但是同时,我在右侧取消引用 b 来为 b.

分配内存

这是如何运作的?

如何同时定义一个指针,因为我使用该指针为其分配内存。 如果他们的行是 Book* b = malloc( sizeof (Book) );,那对我来说很直观,因为 sizeof 询问 type 的大小。但是这里,好像是两个地方同时使用了标识符,是定义的

是否发生了我遗漏的双重传递事件?

它不会取消引用指针。
它仅使用指针指向的大小。
通过查看更奇怪的 Book* b = malloc( sizeof (Book) );,您可能会觉得这似乎是合理的,它实际上根本不访问任何东西,仅使用一种类型。

这个表达式

sizeof *b

未评估。编译器只是试图确定表达式 *b 的类型,而这个类型是 Book。所以实际上这个表达式等同于

sizeof( Book )

变量 b 的类型在其声明符定义完成后已知。所以初始化表达式已经知道初始化对象的类型。

为了更清楚地考虑以下演示程序

#include <stdio.h>

int main(void) 
{
    int x = 10;
    
    size_t n = sizeof( x += 20 );
    
    printf( "n = %zu, x = %d\n", n, x );
    
    return 0;
}

程序输出为

n = 4, x = 10

作为这个表达式

sizeof( x += 20 )

没有计算(编译器只确定表达式的类型)那么变量x的值没有改变。

另一个更复杂的例子。

#include <stdio.h>

int i = 1;

int main(void) 
{
    size_t i[i], b = sizeof( i );

    printf( "b = %zu\n", b );

    return 0;
}

程序输出为

b = 8

在数组 i 的声明中,使用了在文件范围内声明的变量 i,因为数组 i 的声明尚未完成。但是在变量 b 的声明中使用了标识符 i 来表示数组。