【问题标题】:C - void function(void), parameters and return valuesC - void函数(void),参数和返回值
【发布时间】:2017-07-13 22:36:51
【问题描述】:

给了我一个包含多个函数的大型 C 文件,声明如下:

void function_a(void);

函数写在主程序上面:

static void function_a(void) { .... }

在主程序中,这些函数被称为:

function_a();

现在据我所知,上述声明的函数既不使用参数,也没有返回值。但是在这些函数中使用了变量和数组,这些变量和数组并未在这些函数中定义,而仅在主程序中定义。

这真的是正确的 C 语法吗?如果不作为参数传递,函数如何访问主程序中的数据?

此外,主程序使用变量,这些变量是在它调用的函数中计算的。

【问题讨论】:

  • 它们是在主函数中定义的,还是在文件中定义的?
  • 对不起,我刚刚编辑了。它们在主函数上方的文件中定义
  • 请发一个完整的例子而不是片段。
  • 你知道静态作用域的变量是什么吗?
  • 如果变量定义在“上方”main() 和“上方”function_a() - 并且都在同一个文件中 - 那么可以从这两个函数访问变量。任何关于 C 的基础教科书都会告诉你这一点。

标签: c syntax parameters return-value void


【解决方案1】:

请您提供更多背景信息吗?在 C 中,您不能从其他函数访问变量,但可以访问全局变量。

以下程序有效,将输出 3,因为i 是一个全局变量,在任何地方都可见。

#include <stdio.h>

int i = 2;

void plusone() {
        i = i + 1;
}

int main() {
        plusone();
        printf("i = %d\n", i);
}

另一方面,下面的程序将无法编译,因为imain() 函数的本地函数,并且在其他地方不可见。

#include <stdio.h>

void plusone() {
        i = i + 1;
}

int main() {
        int i = 2;
        plusone();
        printf("i = %d\n", i);
}

也就是说,使用全局变量是一种不好的做法,应该避免。

【讨论】:

  • 好的。如果我有另一个只包含变量定义的 C 文件并将这个文件链接到我的包含主程序和其他函数的 C 文件怎么办。来自单独 C 文件的变量是否也是全局变量?
  • @J.M.您必须将这些变量声明为 extern,以便您可以使用它们。
【解决方案2】:

所以这个:

//file_a.c
void function_a(void)
{
    //...
}

使function_a 成为一个不接受任何参数且不返回任何值的函数。这个函数可以被同一个文件 function_a 中的所有其他函数使用,或者在你告诉编译器放在最终程序中的任何其他 .c 文件中。

换句话说,您程序的所有翻译单元都可以访问此功能。如果你在一个名为file_a.c 的文件中有这个函数,并且你还有另一个名为file_z.c 的文件,你可以这样做:

//file_z.c
void function_z(void)
{
    function_a();
}

一切都很好。

另一方面,这个

//file_b.c
static void function_b(void)
{
    //...
}

(为了清楚起见,我重命名了函数)

使function_b 成为一个不接受任何参数且不返回任何值的函数,就像function_a 一样。但是,它还说function_b 在开始或包含file_b.c 的翻译单元中具有静态文件范围。这意味着它不能被其他翻译单元访问。

因此,如果您现在尝试在 file_z.c 中执行此操作:

void function_z(void)
{
    function_b();
}

你会得到编译错误:

file_z.c:(.text+0xa): undefined reference to `function_b'
collect2: error: ld returned 1 exit status

因为每个file_{a,b,z}.c 是(或可能应该是)它们自己的单独翻译单元的起点,并且function_bfile_b.c 中被声明为静态文件范围,所以这个函数只是“不存在”其他翻译单元。

现在,至于在function_b 之前声明的变量,我认为它们看起来有点像这样:

//file_a.c
int array[10];
void function_a(void)
{
    //...
}

这只是声明了一个全局变量。 file_a.c 中的所有函数都可以访问它,前提是它们出现在声明之后。如果您像这样声明它,它也可以被其他翻译单元(如file_b.cfile_z.c)使用:

//file_b.c
extern int array[10];

当您编译所有内容时,翻译单元中以file_b.c 开头的声明将告诉编译器array 不是该file_b.c 内的文件范围变量;而是编译器必须在另一个翻译单元中查找该变量,然后将它们链接在一起,以便所有函数对该 10 个整数块执行相同的操作。

【讨论】:

    【解决方案3】:

    在 C 中,根本不可能访问另一个函数甚至作用域的局部变量。 代码编译是否正确?如果是,这些变量必须在开头或某个头文件中全局定义。 如果不让它们全局访问非参数函数。

    【讨论】:

    • 另一个函数有另一个作用域,所以你的第一句话有点多余。
    • 当然你可以访问你父作用域的变量。
    猜你喜欢
    • 2016-08-28
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    相关资源
    最近更新 更多