我得到了一个大型C文件,其中包含几个声明如下的函数:
void function_a(void);
这些功能写在主程序之上:
static void function_a(void) { .... }
在主程序中,这些函数称为:
function_a();
据我所知,上面声明的函数既不使用参数也不使用返回值。但是,在这些函数中,使用的变量和数组并未在这些函数中定义,而是仅在主程序中定义。
这是非常正确的C语法吗?如果没有作为参数移交,那么函数如何从主程序访问数据?
此外,主程序使用变量,这些变量在它调用的函数中计算。
答案 0 :(得分:5)
请提供更多背景信息?在C中,您无法从另一个函数访问变量,但您可以访问全局变量。
以下程序有效并将输出3,因为i
是一个全局变量,并且随处可见。
#include <stdio.h>
int i = 2;
void plusone() {
i = i + 1;
}
int main() {
plusone();
printf("i = %d\n", i);
}
另一方面,下面的程序将无法编译,因为i
是main()
函数的本地函数,并且在其他地方是不可见的。
#include <stdio.h>
void plusone() {
i = i + 1;
}
int main() {
int i = 2;
plusone();
printf("i = %d\n", i);
}
说使用全局变量是一种不好的做法,应该避免使用。
答案 1 :(得分:0)
所以这个:
//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_b
在file_b.c
中使用静态文件范围声明,所以这个函数只是其他翻译单位“不存在”。
现在,关于在function_b
之前声明的变量,我认为它们看起来有点像这样:
//file_a.c
int array[10];
void function_a(void)
{
//...
}
这只是声明一个全局变量。它可以被file_a.c
中的所有函数访问,前提是它们在声明之后出现。它也可以被其他翻译单元(如file_b.c
或file_z.c
)使用,如果您这样声明:
//file_b.c
extern int array[10];
当您编译所有内容时,翻译单元中以file_b.c
开头的声明将告诉编译器array
不是file_b.c
内的文件范围变量;相反,编译器必须在另一个转换单元中查找该变量,然后将它们链接在一起,以便所有函数对10个整数的块执行相同的操作。
答案 2 :(得分:0)
在C中,根本不可能访问另一个函数甚至范围的局部变量。 代码编译是否正确?如果是,则必须在开头或某个头文件中全局定义这些变量。 如果没有让它们全局化,可以从非参数函数中访问。