在C中的函数内声明的函数是否可在全局范围内使用?

时间:2014-11-06 18:23:05

标签: c function scope

我一直在遇到一个小问题,就是看到人,目前通过评分帮助老师,看到人们在主要范围内宣布职能,而不是在全球范围内,因为我被教导要做,我明白这仍然有效,但我对这些函数会发生什么感到困惑,如果一个函数被调用,在main中声明,在另一个未在所述main中声明的函数中,将会这本身就有用,如果有,为什么呢。不仅仅是main的范围内的函数,因此它不应该保持在本地范围内,或者死C只是在内存中为从全局范围内的函数调用分配空间。宣布,并随后定义?知道我在这方面有点疏忽,试图涵盖这个范围内的所有可能的问题。 我的意思的样本。

int main(){  
  void foo(int bar);
  int boo;
  foo(boo);
  return 0;
}

void foo(int bar){
  ...
}

我试图强调的一点是,函数是可用的,因为它们是相关的,如果有意义的话,通过main,但是应该在全局范围内声明函数,例如

#include <stdio.h>

void roo(void);

int main(){} //Holds the same syntax as above with the function declared within it.
//Function foo is same as defined prior.
//Then function roo is defined but uses foo within itself.

void roo(void){
int boo;
foo(boo);
...
}

由于函数roo在技术上无法访问main范围内的函数,所以代码不能复合,不能完全工作吗?

编辑 -

我有点看到主要的一点是,当前缺少要调用的多个函数,仍然会用于调用函数roo,但如果它包含多个函数,那么它不会是如果从主要的外部扩展了6个函数,那么从roo中调用foo是一种奇怪或不合法的语法。

1 个答案:

答案 0 :(得分:3)

类型检查和链接需要声明。它们仅在编译时存在 - 它们实际上并不创建在编译程序中以任何方式存在的“对象”(例如函数体) - 它们所做的只是在其上放置一个名称,以便其他部分源可以引用该对象,而无需立即处理。 定义创建对象,但声明创建名称。

通过你的例子:

void roo(void);  // roo becomes visible

int main(){  // main is defined, AND becomes visible
    void foo(int bar);  // foo becomes visible
    foo(6);
    roo();
}  // foo is no longer visible

void foo(int bar){ /**/ }  // foo is defined AND becomes visible

void roo(void){  // roo is defined, but was already visible
    foo(6);      //  so this has no effect on other functions
}
  1. roo可以从下面程序中声明它的任何代码中调用,因为它的名称已放在全局范围内,并且可以从所有嵌套作用域中看到。以下代码意识 某处(不知道在哪里),一个名为roo的函数存在且可供使用。

  2. 向下移动到main,会打开一个新范围,并在其中显示foomain使用此信息来呼叫foo。它使用全局范围内的信息来调用roo。范围以main的结尾关闭,foo不再对以下代码可见;它不知道存在任何此类功能。

  3. foo是在全局范围内同时定义和声明的。以下所有代码都知道可以使用名为foo的函数。

  4. 同样适用于roo

  5. 在内存中给予空间的唯一地方是定义的三个点。没有任何声明会导致静态或其他方式分配任何内容。他们所做的就是在其他地方进行分配识别(由链接器解析)。


    所以(我认为是)最初的混淆点:main调用rooroo调用foo,但foo的声明} main中{}不可见} roo。 (听起来你会混淆静态和动态语义:C只有静态范围。)

    这不是问题,因为main不知道roo的内容,也不需要知道其内容(某些编译器执行内联;我们不关心那)。控制离开 main的正文代码并转到程序中的不同点。函数体是每个其他函数的黑盒子;在roo的代码中发生的事情对于其他所有函数都是完全未知的。 roo也不会继承main的范围,因此它 no 知道当时声明的任何内容(全局,本地或其他) - 它使用范围由其自己的身体打开和关闭,以进行名称查找。在该范围内,foo已全局声明(它在页面上的单独固定点继承全局范围),因此roo可以看到foo自愿的。

    每个功能都存在于一个(也就是一个)位置。所有声明都是将可见放置到使用它的代码中。不使用它的代码不需要能够看到它。 main无法看到对foo的嵌套调用,因此此时的任何声明都与它无关。