举例来说:
file2.c
struct myStruct {
int a;
} A;
file1.c
extern struct myStruct A;
int main (void) {
}
使用gcc file1.c file2.c
编译。
- 如果我们不需要知道内部细节,这是在
file1.c
中使用全局变量A
的有效方法吗(例如:函数调用--比如用FILE *
? - 当我们操作内部细节的时候,定义(例如与
file1.c
中的定义相同)是唯一必要的吗? - 如果这些定义不同(我注意到它使用同一个翻译单元中的定义--但这符合标准吗),有什么要说的吗?
前面的结构问题并没有涉及不包含定义的主题--只涉及如何正确地包含定义(在头文件中,在所有使用该结构的文件中都是一样的)
2条答案
按热度按时间jucafojl1#
file1.c
中使用全局变量A
的有效方法吗(例如:函数调用--比如用FILE *
?是的。但是在
A
的类型不完整的情况下,你不能用它做很多事情。获取它的地址是我能想到的最主要的一个。请注意,使用指向
A
的指针与使用A
本身是不同的。file1.c
中的定义相同)是唯一必要的吗?不。如果你想的话,你还需要定义
sizeof
运算符计算类型或类型示例的大小;或我可能漏掉了什么。
如果同一对象的不同声明指定了不兼容的类型,则转换器和程序行为未定义。对于在不同翻译单元中声明的非限定结构类型,“兼容”意味着:
通常,这种兼容性要求是通过在头文件中声明所有想要使用它的文件的类型
#include
来满足的--这避免了引入该类型的不兼容版本的机会。1szpjjfi2#
file1.c
中使用全局变量A
的有效方法吗(例如:函数调用--比如用FILE *
?在
file1.c
中没有使用对象A
,因此file1.c
不包含使用对象A
的有效方法。extern struct myStruct A;
是A
的有效声明。这是对这个名字的有效使用。通过这个声明,对象
A
可以在file1.c
中通过获取其地址&A
来引用,这对于将地址传递给其他文件中定义的例程很有用,其中struct myStruct
的定义是可见的。使用“opaque”类型(在
file1.c
中,我们可以看到有一个类型struct myStruct
,但不能看到它的定义,所以它是“opaque”)的一种更常见的方法是让file2.c
提供访问它们的例程,例如:struct myStruct *GetMyStruct(
parameters);
,为struct myStruct
分配内存并返回指向它的指针。struct myStruct
的例程。(可能只调用free
,但可能更复杂,例如释放struct myStruct
中的数据所指向的内容。struct myStruct
的脚本,例如在其中设置值,从中获取值,或在进一步的计算中使用它。诸如上述的功能通常优于使用外部对象标识符。
另外,
A
不是全局变量。C没有任何全局命名空间。对于具有全局名称的语言,这意味着声明一次名称就可以使其在整个程序中可见。C没有这个。你可以用外部链接声明一个名称,它们可以链接在一起引用同一个对象或函数,但在每个使用该名称的翻译单元中需要有一个声明。这与全球不同。file1.c
中的定义相同)是唯一必要的吗?在大多数情况下,是的,您需要类型的定义。
从技术上讲,您可以使用
&A
来获取A
的地址,将其转换为unsigned char *
,并使用生成的指针来操作A
的字节。因此,可以在没有struct myStruct
类型定义的情况下操作A
,但这不是一件正常的事情。怎么不一样了