Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C函数通常比OOP语言的方法有更多的参数吗?

C函数通常比OOP语言的方法有更多的参数吗?
EN

Stack Overflow用户
提问于 2020-06-16 12:08:51
回答 3查看 233关注 0票数 2

我不得不编写一个C程序,它有600多行代码和大约25个函数。这是我编写的最长的C代码。

我注意到其中一些函数有5个以上的参数。直接从main()调用的对象有更多的参数。它离main()越远,就越少。

我还注意到,我经常不得不将参数传递给函数,并不是因为该函数直接使用该参数,而是该函数调用了另一个需要该参数的函数。

所以看起来就像

代码语言:javascript
运行
AI代码解释
复制
void f1(int a, int b,..., int bar){
    int foo = f2(bar); // the only time 'bar' is used in f1
    .
    .
    .
}

我试图最小化全局变量的使用,但我不得不声明一些全局变量,因为有些参数变得过于冗余。基本上,我必须把这些论点传递给每个函数。

我不是一个经验丰富的程序员,但当我用Java编程时,我认为我从来不需要用5个以上的参数来编写一个方法。

在C语言中传递比其他语言更多的参数是正常的吗?这仅仅是过程编程与面向对象编程的本质吗?还是我只是在写坏的C代码?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-06-16 12:46:03

您对避免太多全局变量的担忧是正确的,因为有了它们,程序往往变得不可维护,特别是当它们越来越大时。让我们通过参数将数据传递给函数。

由于许多原因,使用参数为函数提供执行所需的信息是一个好主意。它首先提供了代码的可读性,但也使编写线程安全函数(可以从不同线程安全调用的函数)变得更加容易。

总之,通常情况下,使用定义一个函数--有时-在堆栈消耗方面,确实会导致效率低下(特别是在嵌入式系统中,只有前3或4个参数使用处理器寄存器,所有其他参数都复制到堆栈中)。

解决方案是使用数据结构。使用struct(与OOP语言(如Java )中调用对象的不同之处),您可以在逻辑实体中对全局数据进行分组。这使您可以在一起定义所有数据,更改其字段,并将其传递给您的函数。通过指针将其传递给,使在其原始位置修改它成为可能。

因此,您的示例函数将成为

代码语言:javascript
运行
AI代码解释
复制
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语言中传递的参数,而不是过程语言:仅仅因为在大多数语言中,调用对象将是过程语言中的一个参数。但是,如果有了精心设计的结构化编程,这种差异就会非常小。

票数 5
EN

Stack Overflow用户

发布于 2020-06-16 13:48:17

在C语言中传递的参数比其他语言多吗?这仅仅是过程编程与面向对象编程的本质吗?还是我只是在写坏的C代码?

这是很普通的事。这是因为在C中,我们没有对象(是的,我们有,但它与Java人所称的对象完全不同),而只是变量(C中的对象)。

因此,您将类的等效值传递给C函数,只需将该类中的每个属性传递给该函数。对矩阵进行反向转换的函数将具有以下签名:

代码语言:javascript
运行
AI代码解释
复制
void inverse (const double *input, size_t ix, size iy, 
              double *output, size_t ox, size_t oy);

在Java或C++中,它看起来如下所示:

代码语言:javascript
运行
AI代码解释
复制
void inverse(const Matrix &input, Matrix &output);

(我不是一个好的C++程序员,所以请原谅我的错误)

关键是Matrix对象包含它们内部的维度成员变量。在面向对象语言中被反对的是数据类型,它是没有方法和公共成员变量的类。

在C中有一个等价的,那就是一个结构。不支持成员函数,除非您使用函数指针(您可以在C中执行OOP,但它非常混乱)。结构基本上是一个没有封装和对私有成员的支持的类。所以它们符合目的。

与数组不同,您不必将它们作为指针传递。这很好:

代码语言:javascript
运行
AI代码解释
复制
struct myStruct {
    int a;
    char b;
    double c[2];
    void **;
};

bool intIsFortyTwo(struct myStruct args) {
    return args.a == 42;
}

还可以返回结构:

代码语言:javascript
运行
AI代码解释
复制
struct myStruct initStruct() {
    struct myStruct ret = {.a=22, .b='a'};
    return ret;
}

一般来说,出于性能原因,指针是可取的。如果不使用指针,则将创建整个结构副本。第一个函数可以是

代码语言:javascript
运行
AI代码解释
复制
bool intIsFortyTwo(struct myStruct *args) {
    return args->a == 42;
}

将结构传递给函数并不是非常常见,但也不奇怪。用它你会发现它很有用。

票数 3
EN

Stack Overflow用户

发布于 2020-06-16 12:46:34

为了扩展注释中的观点,在替代方法是大量单个参数时,将单个指针传递给struct的效率得到了提高,因为与传递多个指针或代表单个参数的值相比,传递单个指针(只要它小于1023)的sizeof很小。与多于3或4个参数的任何参数相比,读一个参数也容易得多。

因此,即使使用一个相对较小的原型示例:void f1(int a, int b, int bar) (删除了省略号)。给定32位目标,具有4字节/int

代码语言:javascript
运行
AI代码解释
复制
sizeof a + sizeof b + sizeof bar == 12bytes

与指向具有超过1000个成员的结构的指针的大小相比

代码语言:javascript
运行
AI代码解释
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62416770

复制
相关文章
C语言 | 函数参数
以上,如果你看了觉得对你有所帮助,就给小林点个赞,分享给身边的人叭,这样小林也有更新下去的动力,跪谢各位父老乡亲啦~
小林C语言
2021/04/15
2.8K0
C语言 | 函数参数
【C语言笔记】函数指针作为函数的参数
函数指针有两种常用的用法,一种是作为结构体成员,关于函数指针作为结构体成员的用法可移步至上一篇【C语言笔记】函数指针作为结构体成员进行查看。另一种是函数指针作为函数的参数。这一篇分享的是函数指针作为函数的参数。
正念君
2019/06/26
11.2K0
【C语言笔记】函数指针作为函数的参数
C语言函数参数是如何传递的?
我们可能听过C语言中的传值和传指针,在其他语言中,也有传引用一说,那么他们到底有什么区别呢?如果你还不能准确地分辨,就该好好了解一下了。
诸葛青云
2019/06/23
4.3K0
C语言函数参数是如何传递的?
C++带参数的构造函数 | 有参构造函数
在C++中,程序员希望对不同的对象赋予不同的初值,可以采用带参数的构造函数,在调用不同对象的构造函数时,从外面将不同的数据传递给构造函数, 以实现不同的初始化。
小林C语言
2021/01/28
4.3K0
C++带参数的构造函数 | 有参构造函数
c语言 函数的参数传递示例_remquo()函数与C ++中的示例
remquo() function is a library function of cmath header. It is used to calculate the remainder and quotient, this function is the same as the remainder() function, but this function also stores the quotient that can be used further. It accepts three parameters (numerator, denominator, and quotient) and returns the remainder, assigns the quotient in the third parameter which should be a pointer.
用户7886150
2021/02/11
1.6K0
【C语言笔记】函数参数压栈的顺序?
按照日常习惯来看,C语言的函数参数压栈顺序是从左到右吧?但是事实却是相反的,C语言函数参数压栈顺序是从右到左的。下面看一个程序:
正念君
2019/07/01
3.9K3
C语言到C++的OOP 面向对象编程
1、全面兼容C,C的许多代码不经修改就可以为Cpp所用,用C编写的库函数和实用软件可以用于Cpp。
小林C语言
2020/12/21
3.3K0
C语言到C++的OOP 面向对象编程
C语言 深度探究具有不定参数的函数
C语言虽然不支持泛型编程(至少C98是这样的),但是C语言却支持不定参数的函数,这里我深究一下里面的原理,并且学会它的使用,自己简单实现一个简单的printf函数。 注:这里使用的IDE为 vs2022
苏州程序大白
2022/06/12
5810
C语言 深度探究具有不定参数的函数
你知道C语言中的危险函数吗?
"缓冲区溢出"漏洞是一个由来已久的漏洞类型,虽然现代操作系统的编译器,已经可以很大程度的阻止此类型漏洞的出现,但是作为一名合格的C程序员,还是有必要对此类漏洞的原理进行一定了解的,今天我就带大家对此类漏洞进行分析。
Power7089
2020/07/27
1.7K0
你知道C语言中的危险函数吗?
c语言可重入函数_c语言不可重入函数有哪些
可重入函数指一个可同时被多个任务调用的过程,当一个函数满足下列条件时多为不可重入函数
全栈程序员站长
2022/11/17
8660
C语言自定义函数的方法
int main(void)//主函数 { fun();//调用fun函数 “
全栈程序员站长
2022/07/02
2.4K0
C语言函数求参数顺序问题
对于函数func,先求右边x+=2参数,返回x=8,然后计算结果。也就是传递给形参的两个值都是8,返回值为16。
用户6755376
2019/11/19
2.6K0
7.3 C语言数组作为函数参数
2、用数组元素作实参时,向形参变量传递的是数组元素的值,而用数组名作函数实参时,向形参传递的是数组首元素的地址。
小林C语言
2020/12/07
2.9K0
7.3 C语言数组作为函数参数
【说站】c语言中函数参数类型的探究
函数中的参数个数可以是0,也可以是一个或多个参数。下面我们带着这三种不同的情况,分别在c语言中进行讨论。
很酷的站长
2022/11/24
7950
小朋友学C语言(34):main函数的参数
C/C++中的main()函数,可以带形式参数,也可以不带形式参数。这两种形式分别为: 1)int main() 2)int main(int argc, char *argv[]) 或者 int main(int argc, char **argv) 因为main()函数通常是由操作系统调用的,所以平时写程序,基本上不用带参数。但是从学习的角度来看,了解一下参数也是有益处的。 第一个参数,argc是argument count的缩写,表示“参数个数”。 第二个参数,argv[]是argument vect
海天一树
2018/04/17
1.9K0
小朋友学C语言(34):main函数的参数
C语言函数不定参数实现方式
函数如何实现不定参数: 由于在C语言中没有函数重载,解决不定数目函数参数问题变得比较麻烦,即使采用C++,如果参数个数不能确定,也很难采用函数重载。对这种情况 ,提出了指针参数来解决问题。 (1)va_list 定义了一个指针arg_ptr, 用于指示可选的参数. (2)va_start(arg_ptr, argN) 使参数列表指针arg_ptr指向函数参数列表中的第一个可选参数,argN是位于第一个可选参数之前的固定参数, 或者说最后一个固定参数.如有一va 函数的声明是void va_test(ch
233333
2018/03/07
2.5K0
C语言指针变量作为函数参数
自学气象人
2023/06/20
2070
C语言指针变量作为函数参数
你真的知道C语言函数调用的内幕吗?
C语言使用函数调用,我们再熟悉不过了,但是函数调用在内存中究竟发生了什么真的清楚吗?只有搞清楚内存里的内幕,才算完全搞懂函数的调用。
混说Linux
2022/11/18
5580
你真的知道C语言函数调用的内幕吗?
C语言中函数参数传递的三种方式
(1)传值,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数,因而在函数里对形参的改变不会影响到函数外的变量的值。 (2)传址,就是传变量的地址赋给函数里形式参数的指针,使指针指向真实的变量的地址,因为对指针所指地址的内容的改变能反映到函数外,也就是能改变函数外的变量的值。 (3)传引用,实际是通过指针来实现的,能达到使用的效果如传址,可是使用方式如传值。 说几点建议:如果传值的话,会生成新的对象,花费时间和空间,而在退出函数的时候,又会销毁该对象,花费时间和空间。 因而如果int,char等固有类型,而是你自己定义的类或结构等,都建议传指针或引用,因为他们不会创建新的对象。
全栈程序员站长
2022/07/02
4.6K0
C语言中函数参数传递的三种方式
点击加载更多

相似问题

在JavaScript中存储密码和in的最佳方法是什么?

12

在JavaScript中存储/读取大型矩阵的最佳方法是什么?

13

在JavaScript中,测试给定参数是否为平方数的最佳方法是什么?

77

在非常大的树上执行DFS的最佳方法是什么?

27

截断二进制数的最佳方法

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档