Passing by reference in C

后端 未结 17 2208
梦如初夏
梦如初夏 2020-11-21 23:26

If C does not support passing a variable by reference, why does this work?

#include 

void f(int *j) {
  (*j)++;
}

int main() {
  int i = 20;         


        
相关标签:
17条回答
  • 2020-11-21 23:44

    In C, Pass-by-reference is simulated by passing the address of a variable (a pointer) and dereferencing that address within the function to read or write the actual variable. This will be referred to as "C style pass-by-reference."

    Source: www-cs-students.stanford.edu

    0 讨论(0)
  • 2020-11-21 23:44

    Because there is no pass-by-reference in the above code. Using pointers (such as void func(int* p)) is pass-by-address. This is pass-by-reference in C++ (won't work in C):

    void func(int& ref) {ref = 4;}
    
    ...
    int a;
    func(a);
    // a is 4 now
    
    0 讨论(0)
  • 2020-11-21 23:48

    You're passing a pointer(address location) by value.

    It's like saying "here's the place with the data I want you to update."

    0 讨论(0)
  • 2020-11-21 23:48

    What you are doing is pass by value not pass by reference. Because you are sending the value of a variable 'p' to the function 'f' (in main as f(p);)

    The same program in C with pass by reference will look like,(!!!this program gives 2 errors as pass by reference is not supported in C)

    #include <stdio.h>
    
    void f(int &j) {    //j is reference variable to i same as int &j = i
      j++;
    }
    
    int main() {
      int i = 20;
      f(i);
      printf("i = %d\n", i);
    
      return 0;
    }
    

    Output:-

    3:12: error: expected ';', ',' or ')' before '&' token
                 void f(int &j);
                            ^
    9:3:  warning: implicit declaration of function 'f'
                   f(a);
                   ^
    
    0 讨论(0)
  • 2020-11-21 23:49

    That is not pass-by-reference, that is pass-by-value as others stated.

    The C language is pass-by-value without exception. Passing a pointer as a parameter does not mean pass-by-reference.

    The rule is the following:

    A function is not able to change the actual parameters value.


    Let's try to see the differences between scalar and pointer parameters of a function.

    Scalar variables

    This short program shows pass-by-value using a scalar variable. param is called the formal parameter and variable at function invocation is called actual parameter. Note incrementing param in the function does not change variable.

    #include <stdio.h>
    
    void function(int param) {
        printf("I've received value %d\n", param);
        param++;
    }
    
    int main(void) {
        int variable = 111;
    
        function(variable);
        printf("variable %d\m", variable);
        return 0;
    }
    

    The result is

    I've received value 111
    variable=111
    

    Illusion of pass-by-reference

    We change the piece of code slightly. param is a pointer now.

    #include <stdio.h>
    
    void function2(int *param) {
        printf("I've received value %d\n", *param);
        (*param)++;
    }
    
    int main(void) {
        int variable = 111;
    
        function2(&variable);
        printf("variable %d\n", variable);
        return 0;
    }
    

    The result is

    I've received value 111
    variable=112
    

    That makes you believe that the parameter was passed by reference. It was not. It was passed by value, the param value being an address. The int type value was incremented, and that is the side effect that make us think that it was a pass-by-reference function call.

    Pointers - passed-by-value

    How can we show/prove that fact? Well, maybe we can try the first example of Scalar variables, but instead of scalar we use addresses (pointers). Let's see if that can help.

    #include <stdio.h>
    
    void function2(int *param) {
        printf("param's address %d\n", param);
        param = NULL;
    }
    
    int main(void) {
        int variable = 111;
        int *ptr = &variable;
    
        function2(ptr);
        printf("ptr's address %d\n", ptr);
        return 0;
    }
    

    The result will be that the two addresses are equal (don't worry about the exact value).

    Example result:

    param's address -1846583468
    ptr's address -1846583468
    

    In my opinion this proves clearly that pointers are passed-by-value. Otherwise ptr would be NULL after function invocation.

    0 讨论(0)
  • 2020-11-21 23:49

    I think C in fact supports pass by reference.

    Most languages require syntactic sugar to pass by reference instead of value. (C++ for example requires & in the parameter declaration).

    C also requires syntactic sugar for this. It's * in the parameter type declaration and & on the argument. So * and & is the C syntax for pass by reference.

    One could now argue that real pass by reference should only require syntax on the parameter declaration, not on the argument side.

    But now comes C# which does support by reference passing and requires syntactic sugar on both parameter and argument sides.

    The argument that C has no by-ref passing cause the the syntactic elements to express it exhibit the underlying technical implementation is not an argument at all, as this applies more or less to all implementations.

    The only remaining argument is that passing by ref in C is not a monolithic feature but combines two existing features. (Take ref of argument by &, expect ref to type by *.) C# for example does require two syntactic elements, but they can't be used without each other.

    This is obviously a dangerous argument, cause lots of other features in languages are composed of other features. (like string support in C++)

    0 讨论(0)
提交回复
热议问题