cfunctionargumentsprocedural-programming

Do C functions generally have more arguments than OOP languages' methods?


I had to write a C program with more than 600 lines and about 25 functions. This is the longest C code that I've written.

I noticed that some of the functions have more than 5 arguments. The ones that are directly called from main() have more arguments. The further away it goes from main(), the fewer.

I also noticed that I frequently had to pass an argument to a function, not because that function directly uses that argument, but the function calls another function that needs that argument.

So it would look something like

void f1(int a, int b,..., int bar){
    int foo = f2(bar); // the only time 'bar' is used in f1
    .
    .
    .
}

I tried to minimize the use of global variables, but I had to declare some global variable because some arguments became way too redundant. Basically I had to pass those arguments to every function.

I'm not an experienced programmer but when I programmed in Java, I don't think I ever needed to write a method with more than 5 arguments.

Is it normal in C to pass way more arguments than in other languages? Is it just the nature of Procedural Programming vs OOP? Or am I just writing bad C code?


Solution

  • Your concerns about avoiding too many global variables are correct, because with them programs tend to become unmaintainable, especially when they grow in size. So let's pass data to functions through parameters.

    Using parameters to provide your functions with the information they need to execute is a good idea for many reasons. It offers first of all the readability of the code, but also make it easier writing thread safe functions (functions that can be called safely from different threads).

    Anyway, generally speaking, defining a function with too many parameters sometimes may indeed cause inefficiency in terms of stack consumption (especially in embedded systems, where only the first 3 or 4 parameters use the processor registers, with all the others parameters copied to the stack).

    The solution is using data structures. With structs (not so different from what, in OOP languages such as Java, you would call objects) you can group together your global data in logical entities. This makes possible to define of all your data together, to change its fields, and to pass it to your functions. And passing it by pointer makes possible modifying it in its original location.

    So your example functions would become

    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;
    }
    

    You need to change f2() passing it more parameters? Well, forward the pointer to MyData_t to it and you'll access all the variables you need.


    In conclusion, to answer your question, probably a statistical analysis would result in less parameters passed in OOP languages rather than procedural languages: just because in most of them the calling object would be a parameter in a procedural language. But with well designed structured programming, this difference would be very small.