繁体   English   中英

C 对象的顺序是否重要?

[英]Does the order of C objects matter?

C 对象出现在文件上的顺序是否重要?

例如,在函数中,如果我创建了两个函数并且上面的一个引用了另一个函数,它会起作用吗? (是的,我试过了。)对于 static 函数、INLINE 函数等是否同样有效? 结构的效果是否相同? 如果我引用在.c 文件中进一步定义的结构会发生什么?

这是任何扩展编译器特定的吗? 在这种情况下编译器如何工作? 它是否首先扫描整个文件以查找所有声明/定义,然后尝试取消引用函数/符号?

首先,如果通过“如果我创建两个函数并且上面的一个引用另一个函数会起作用吗?” 你的意思是这样的:

int foo()
{
    return bar();
}

int bar()
{
    return 0;
}

然后编译器可能会对bar()是什么进行有根据的猜测,但如果bar()尚未声明,它至少会发出警告。 对于无法调用的符号(如变量或类型),如果在声明它们之前使用它们,那将是一个彻头彻尾的错误。

在 C 中,无论何时使用标识符(无论标识符的种类:它可能是 function、变量、类型等),都应事先声明。 您可以添加到任何标识符的各种修饰符(如您所说, staticinline和所有其他修饰符)对此没有影响。

不要混淆声明定义 声明只是告诉编译器名称存在; 定义实际上告诉编译器它是什么。

例如,这是一个定义:

int bar() { return 4; }

注意它是如何有一个主体的,里面有(简单的)代码。

这是匹配的声明:

int bar();

编译器一看到它的声明或定义,就会很乐意接受 function 的使用。 出于组织原因和更好的灵活性,通常最好在 C 文件的顶部(或在包含的 header 文件中)编写所有函数的声明,然后是定义。

所以,我的第一个例子应该是这样的:

int foo();
int bar();

int foo()
{
    return bar();
}

int bar()
{
    return 0;
}

使用 C 代码上方的声明,我可以以任何我喜欢的方式更改函数的顺序。

通常必须在您使用它的地方定义某些内容。 您可以针对不同的情况以不同的方式避免这种情况。

对于函数,只需在上面调用它的地方提供一个原型,一切都会好起来的。

int trol(int a, int b);

// use trol(int, int)

int trol(int a, int b) { }

如果您有两个函数ab ,并且它们相互调用并按以下顺序定义ab ,那么您必须在a的定义之上提供b的原型。 a的原型不是必需的,因为它是在上面定义的,它在b内部使用。 那么编译器就没有问题了。

函数的另一种特殊情况是您可以使用 function 而不声明它,编译器将尝试从调用中推断签名。 这个答案很好地解释了我认为: 必须在 C 中声明 function 原型?

对于struct ,您可以通过提供前向声明在实际定义它们之前使用指向它们的指针(但您不能访问任何字段):

struct s;

// use s*'s

struct s { };

(上面的场景有利于递归数据结构,如链表和树;您可以在完全定义之前使用指向struct的指针,因为任何类型的指针的大小都是恒定的。)

这很重要,因为如果编译器不知道 function 是什么 - 它会尝试“猜测”(创建具有匹配参数的默认int foo()原型),如果你的调用不正确 - 你会有不匹配(构建错误,隐式转换,等等)。

在调用 function 之前(通过原型也就是前向声明)声明它是一种常见的做法(如果甚至不需要)。

对于具有可变参数列表的函数(如printf ),您必须有一个前向声明才能使它们正常工作。 例如,此代码将无法编译:

int foo(int a)
{
    b(a);
    b("hello", "kitty");
}

void b(int a, ...)
{

    printf("%d", a);
}

但这 - 将:

#include <stdio.h>
int foo(int a)
{
    return b(a);
}

int b(int a)
{

    return printf("%d", a);
}

(带有关于隐式前向声明的警告)

因此,为了避免处理文件中对象的顺序 - 使用原型(前向声明)让编译器知道接下来的内容。

根据我的经验,C 中的所有内容都必须在引用之前用引用的“对象”编写。 我不认为这是特定于任何编译器的,但也许有些我还没有找到。 基本上,一切都必须是:

Object Declaration
...
Object Reference

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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