我不得不编写一个C程序,它有600多行代码和大约25个函数。这是我编写的最长的C代码。
我注意到其中一些函数有5个以上的参数。直接从main()调用的对象有更多的参数。它离main()越远,就越少。
我还注意到,我经常不得不将参数传递给函数,并不是因为该函数直接使用该参数,而是该函数调用了另一个需要该参数的函数。
所以看起来就像
void f1(int a, int b,..., int bar){
int foo = f2(bar); // the only time 'bar' is used in f1
.
.
.
}
我试图最小化全局变量的使用,但我不得不声明一些全局变量,因为有些参数变得过于冗余。基本上,我必须把这些论点传递给每个函数。
我不是一个经验丰富的程序员,但当我用Java编程时,我认为我从来不需要用5个以上的参数来编写一个方法。
在C语言中传递比其他语言更多的参数是正常的吗?这仅仅是过程编程与面向对象编程的本质吗?还是我只是在写坏的C代码?
发布于 2020-06-16 12:46:03
您对避免太多全局变量的担忧是正确的,因为有了它们,程序往往变得不可维护,特别是当它们越来越大时。让我们通过参数将数据传递给函数。
由于许多原因,使用参数为函数提供执行所需的信息是一个好主意。它首先提供了代码的可读性,但也使编写线程安全函数(可以从不同线程安全调用的函数)变得更加容易。
总之,通常情况下,使用定义一个函数--有时-在堆栈消耗方面,确实会导致效率低下(特别是在嵌入式系统中,只有前3或4个参数使用处理器寄存器,所有其他参数都复制到堆栈中)。
解决方案是使用数据结构。使用struct
(与OOP语言(如Java )中调用对象的不同之处),您可以在逻辑实体中对全局数据进行分组。这使您可以在一起定义所有数据,更改其字段,并将其传递给您的函数。通过指针将其传递给,使在其原始位置修改它成为可能。
因此,您的示例函数将成为
typedef struct
{
int a;
int b;
int bar;
} MyData_t;
void f1( MyData_t *data )
{
int foo = f2( data->bar );
/* ... */
}
int main( void )
{
MyData_t d = { 5, 7, 9 };
f1( &d );
return 0;
}
您需要更改f2()
,传递更多参数吗?那么,将指向MyData_t
的指针转发到它,您将访问所需的所有变量。
最后,回答您的问题,统计分析可能会减少在OOP语言中传递的参数,而不是过程语言:仅仅因为在大多数语言中,调用对象将是过程语言中的一个参数。但是,如果有了精心设计的结构化编程,这种差异就会非常小。
发布于 2020-06-16 13:48:17
在C语言中传递的参数比其他语言多吗?这仅仅是过程编程与面向对象编程的本质吗?还是我只是在写坏的C代码?
这是很普通的事。这是因为在C中,我们没有对象(是的,我们有,但它与Java人所称的对象完全不同),而只是变量(C中的对象)。
因此,您将类的等效值传递给C函数,只需将该类中的每个属性传递给该函数。对矩阵进行反向转换的函数将具有以下签名:
void inverse (const double *input, size_t ix, size iy,
double *output, size_t ox, size_t oy);
在Java或C++中,它看起来如下所示:
void inverse(const Matrix &input, Matrix &output);
(我不是一个好的C++程序员,所以请原谅我的错误)
关键是Matrix
对象包含它们内部的维度成员变量。在面向对象语言中被反对的是数据类型,它是没有方法和公共成员变量的类。
在C中有一个等价的,那就是一个结构。不支持成员函数,除非您使用函数指针(您可以在C中执行OOP,但它非常混乱)。结构基本上是一个没有封装和对私有成员的支持的类。所以它们符合目的。
与数组不同,您不必将它们作为指针传递。这很好:
struct myStruct {
int a;
char b;
double c[2];
void **;
};
bool intIsFortyTwo(struct myStruct args) {
return args.a == 42;
}
还可以返回结构:
struct myStruct initStruct() {
struct myStruct ret = {.a=22, .b='a'};
return ret;
}
一般来说,出于性能原因,指针是可取的。如果不使用指针,则将创建整个结构副本。第一个函数可以是
bool intIsFortyTwo(struct myStruct *args) {
return args->a == 42;
}
将结构传递给函数并不是非常常见,但也不奇怪。用它你会发现它很有用。
发布于 2020-06-16 12:46:34
为了扩展注释中的观点,在替代方法是大量单个参数时,将单个指针传递给struct的效率得到了提高,因为与传递多个指针或代表单个参数的值相比,传递单个指针(只要它小于1023)的sizeof
很小。与多于3或4个参数的任何参数相比,读一个参数也容易得多。
因此,即使使用一个相对较小的原型示例:void f1(int a, int b, int bar)
(删除了省略号)。给定32位目标,具有4字节/int
sizeof a + sizeof b + sizeof bar == 12bytes
与指向具有超过1000个成员的结构的指针的大小相比
typedef struct {
int a;
int b;
... say 1000 more ints
int bar;
}data_t;
data_t *pData
pData = &data_t;//point pointer back to location t_data.
sizeof pData == 8 bytes
https://stackoverflow.com/questions/62416770
复制相似问题