【发布时间】:2021-12-17 17:55:53
【问题描述】:
我有以下文件结构。我知道指针需要分配内存。文件 A 由达芬奇生成。主要是我写的。
// File A
typedef struct {
int v1;
}s1;
struct s2{
s1 *p1;
};
extern const struct s2 * const p3; // Expr 1
#define untilp1() (*(&p3->p1)) // Expr 2
// File main
#include <stdio.h>
#include "FileA.h"
int main()
{
int v2 = 10;
untilp1()->v1 = v2; // This line results in failure
return 0;
}
Q1 - 我不明白表达式 1。具体来说,我不明白 expr 1 中使用了这么多 const 关键字。我知道术语 extern 的含义。在这种情况下,我猜一个常量指针p3 是未定义的,未声明的,但编译器知道它指向常量结构s2。它是否正确?如果你能说得更清楚,请详细说明。
Q2 - 我不明白表达式 2。具体来说,我不明白 (*(&p3->p2)) 发生了什么。我知道#define 的含义。请详细解释一下表达式。
Q3 - 在一般编码中,我分配内存,例如在我声明使用指针之前使用malloc。当这些文件由达芬奇生成时,我不确定这是如何处理的。但是我没有看到我的任何同事使用 malloc 等。有谁知道我是否可以使用p3 或untilp1() 将v2 的值分配给v1?
谢谢。
【问题讨论】:
-
Expr 1表示p3是一个指向const struct s2的const指针。阅读更多here。 -
你可能会觉得这个网站很有趣:cdecl
-
Expr 2将用*(&p3->p1)->v1替换行untilp1()->v1 = v2;。 -
*(&p3->p1)只是写(p3->p1)的一种混淆方式。编写此类代码的唯一原因是程序员不知道运算符的优先级。这个代码库似乎有很大的代码味道。 -
(c)
#define untilp1() *(&p3->p1)是一个设计糟糕的定义,原因有两个。一,*(&p3->p1)等价于p3->p1,显然没有理由使用前一种形式。第二,众所周知,在宏中使用括号是一种很好的做法,如在#define untilp1() (*(&p3->p1))中,以避免使用宏的优先级问题,这就是在untilp1()->v1 = v2;中发生的导致错误的问题。 (->的优先级高于*,因此被解析为*((&p3->p1)->v1)。)如果该代码是由达芬奇软件生成的,那么这些代码的质量就会受到质疑。
标签: c pointers struct extern davinci