pass by reference is valid?

Discussion in 'C Programming' started by lisp9000@gmail.com, Sep 15, 2007.

  1. Guest

    I've read that C allows two ways to pass information between
    functions:

    o Pass by Value
    o Pass by Reference

    I was talking to some C programmers and they told me there is no such
    thing as pass by reference in C since you are just passing an address
    (or a pointer value address I guess?). So I was wondering is this
    correct?

    Also I read that, "C does not have run-time typing". What does this
    mean and is it true?

    C just cares that you pass the correct type of arguments (int, float,
    char, ...) and doesn't care about the value or variable/data structure
    name is that also correct?

    I wrote 3 simple test programs for the different ways to pass
    information in functions. Any critiques/improvements would be welcome:


    /* Example 1 */

    /* func.c */

    int swap(int a, int b)
    {
    a = b;
    return a;
    }

    /* main.c */

    int b =1;
    int c = 2;

    int main(void)
    {

    swap(b,c);
    printf("%d",c);
    return 0;
    }

    BTW in my example of func.c and main.c here it doesn't seem to matter
    if I make b, c global variables or local. In writing C how do I best
    decide if I should make variables global or local, or if it won't
    affect the purpose of the code should I not care?

    /* Example 2 */

    /* func2.c */

    int swap(int &a, int &b)
    {
    a = b;
    return a;
    }

    /* main2.c */

    int *b =1;
    int *c = 2;

    int main(void)
    {

    swap(&b,&c);
    printf("%d",&c);
    return 0;
    }

    /* Example 3 */

    /* func3.c */

    int swap(int *a, int *b)
    {
    *a = *b;
    return *a;
    }

    /* main3.c */

    int *b =1;
    int *c = 2;

    int main(void)
    {

    swap(*b,*c);
    printf("%d",&c);
    return 0;
    }

    PS: I'm learning about closures in Lisp and they seem nifty, but I
    read C doesn't have them. Or is this not quite true?

    Lisp 9000
     
    , Sep 15, 2007
    #1
    1. Advertising

  2. Flash Gordon Guest

    wrote, On 15/09/07 08:55:
    > I've read that C allows two ways to pass information between
    > functions:
    >
    > o Pass by Value
    > o Pass by Reference


    You may not have read the book carefully enough, or it may
    be a bad book.

    > I was talking to some C programmers and they told me there is no such
    > thing as pass by reference in C since you are just passing an address
    > (or a pointer value address I guess?). So I was wondering is this
    > correct?


    The C programmers are correct. Of course, passing a pointer by value
    allows you to do something very similar to passing by reference
    foo(&i);
    foo can now modify the value of i because you passed a pointer to it.

    > Also I read that, "C does not have run-time typing". What does this
    > mean and is it true?


    In some languages you can do something like:
    func(var)
    if var is an int then do something
    else if var is a string do something else

    In C you can't.

    > C just cares that you pass the correct type of arguments (int, float,
    > char, ...) and doesn't care about the value or variable/data structure
    > name is that also correct?


    There are some promotions which are automatically performed, so the
    above is at least misleading.

    > I wrote 3 simple test programs for the different ways to pass
    > information in functions. Any critiques/improvements would be welcome:
    >
    > /* Example 1 */
    >
    > /* func.c */
    >
    > int swap(int a, int b)
    > {
    > a = b;
    > return a;
    > }


    Why make swap return an int? I would say that void makes more sense.
    Obviously it does not work as you know.

    > /* main.c */
    >
    > int b =1;
    > int c = 2;
    >
    > int main(void)
    > {
    >
    > swap(b,c);
    > printf("%d",c);
    > return 0;
    > }
    >
    > BTW in my example of func.c and main.c here it doesn't seem to matter
    > if I make b, c global variables or local. In writing C how do I best
    > decide if I should make variables global or local, or if it won't
    > affect the purpose of the code should I not care?


    The simple rule for beginners is make them local. When you know a bit
    more you make them local unless you have a *very* good reason not to.
    The reason for this is that if a variable is local you can easily see
    where it is modified. If it is global you have to check the entire
    1,000,000 line program to see what affects it.

    > /* Example 2 */
    >
    > /* func2.c */
    >
    > int swap(int &a, int &b)


    A syntax error in C. If you compiler accepts it then it is not working
    as a C compiler.

    <snip>

    > /* Example 3 */
    >
    > /* func3.c */
    >
    > int swap(int *a, int *b)
    > {
    > *a = *b;
    > return *a;
    > }


    Again, I would not return a value.
    void swap(int *a, int *b)
    {
    int tmp = *a;
    *a = *b;
    *b = tmp;
    }
    You should be able to work out the reasons for the rest of the changes
    since you called the function 'swap' not 'assign'.

    > /* main3.c */
    >
    > int *b =1;
    > int *c = 2;


    No, no, a thousand time no. You want int variables, not pointers to int.
    A pointer points somewhere, the value it points to is held somewhere
    else and you have to provide that place.

    > int main(void)
    > {
    >
    > swap(*b,*c);


    With b and c being pointers, this would pass the value pointed to (if
    the rest was correct) *not* the pointer value. The names of the
    variables are 'b' and 'c' *not* '*b' and '*c'.

    > printf("%d",&c);


    I don't even know what you were thinking.

    > return 0;
    > }


    int main(void)
    {
    int b=2;
    int c=3;
    printf("%d %d\n",b,c);
    swap(&b,&c);
    printf("%d %d\n",b,c);
    return 0;
    }

    You use & to get a pointer to a variable.

    > PS: I'm learning about closures in Lisp and they seem nifty, but I
    > read C doesn't have them. Or is this not quite true?


    C does not have them.

    Personally I think trying to learn two languages at once is a mistake.
    --
    Flash Gordon
     
    Flash Gordon, Sep 15, 2007
    #2
    1. Advertising

  3. Army1987 Guest

    On Sat, 15 Sep 2007 07:55:47 +0000, wrote:

    > I've read that C allows two ways to pass information between
    > functions:
    >
    > o Pass by Value
    > o Pass by Reference
    >
    > I was talking to some C programmers and they told me there is no such
    > thing as pass by reference in C since you are just passing an address
    > (or a pointer value address I guess?). So I was wondering is this
    > correct?
    >
    > Also I read that, "C does not have run-time typing". What does this
    > mean and is it true?
    >
    > C just cares that you pass the correct type of arguments (int, float,
    > char, ...) and doesn't care about the value or variable/data structure
    > name is that also correct?
    >
    > I wrote 3 simple test programs for the different ways to pass
    > information in functions. Any critiques/improvements would be welcome:
    >
    >
    > /* Example 1 */
    >
    > /* func.c */
    >
    > int swap(int a, int b)
    > {
    > a = b;
    > return a;
    > }
    >
    > /* main.c */
    >
    > int b =1;
    > int c = 2;
    >
    > int main(void)
    > {
    >
    > swap(b,c);
    > printf("%d",c);
    > return 0;
    > }
    >
    > BTW in my example of func.c and main.c here it doesn't seem to matter
    > if I make b, c global variables or local.

    Because the parameter b would shadow out the global variable. This
    is not a very Good Thing to do in general...

    In writing C how do I best
    > decide if I should make variables global or local, or if it won't
    > affect the purpose of the code should I not care?

    No, you should make them local unless there is a good reason to do
    otherwise. (BTW, the terms the C Standard uses are "file scope"
    and "block scope").
    >
    > /* Example 2 */
    >
    > /* func2.c */
    >
    > int swap(int &a, int &b)

    No such thing in C. You were thinking about C++? If so, go to
    comp.lang.c++.
    > {
    > a = b;
    > return a;
    > }
    >
    > /* main2.c */
    >
    > int *b =1;

    This is a constraint violation, though on some compilers it does
    compile to the equivalent of int *b = (int *)1. Simplifying a bit,
    b contains the address of the memory location 1. It doesn't even
    need to be correctly aligned to contain an int. This is definitely
    *not* what you were trying to do.
    > int *c = 2;
    >
    > int main(void)
    > {
    >
    > swap(&b,&c);

    &b is the address of the object b, which in turn contains the
    address of memory location 1.
    > printf("%d",&c);
    > return 0;
    > }
    >
    > /* Example 3 */
    >
    > /* func3.c */
    >
    > int swap(int *a, int *b)
    > {
    > *a = *b;
    > return *a;
    > }
    >
    > /* main3.c */
    >
    > int *b =1;
    > int *c = 2;
    >
    > int main(void)
    > {
    >
    > swap(*b,*c);

    *b means the int located at the address contained in b. And you
    are likely not to be allowed to read from address 1. Ka-Boom!
    > printf("%d",&c);
    > return 0;
    > }


    Try this:
    int swap(int *a, int *b)
    {
    *a = *b;
    return *a;
    }
    int main(void)
    {
    int b = 1;
    int c = 2;
    swap(&b, &c);
    printf("%d %d\n", b, c);
    return 0;
    }
    --
    Army1987 (Replace "NOSPAM" with "email")
    If you're sending e-mail from a Windows machine, turn off Microsoft's
    stupid “Smart Quotes†feature. This is so you'll avoid sprinkling garbage
    characters through your mail. -- Eric S. Raymond and Rick Moen
     
    Army1987, Sep 15, 2007
    #3
  4. wrote:

    > I've read that C allows two ways to pass information between
    > functions:
    >
    > o Pass by Value
    > o Pass by Reference
    >
    > I was talking to some C programmers and they told me there is no such
    > thing as pass by reference in C since you are just passing an address
    > (or a pointer value address I guess?). So I was wondering is this
    > correct?


    It depends on how 'Pass by Reference' is interpreted.
    In general computer science, passing a pointer to some data qualifies
    as 'Pass by Reference'.
    In the context of C++, and for those who want to distinguish between the
    parameter passing methods of C and C++, the term 'Pass by Reference'
    gets reserved for the situation that C++ reference types are used. The
    mechanism of passing a pointer is then referred to as 'Pass by
    Address'.

    You could also argue that C only has 'Pass by Value', because if you are
    passing a pointer to something, then it is the value of the pointer
    that gets passed.

    >
    > Also I read that, "C does not have run-time typing". What does this
    > mean and is it true?


    You will have to ask whoever made that statement what they meant with
    the term 'run-time typing'.
    One main characteristic of C is that all types used in the program, as
    well as the exact type for each variable, must be known to the
    compiler.

    >
    > C just cares that you pass the correct type of arguments (int, float,
    > char, ...) and doesn't care about the value or variable/data structure
    > name is that also correct?


    Yes, that is correct.

    >
    > I wrote 3 simple test programs for the different ways to pass
    > information in functions. Any critiques/improvements would be welcome:
    >
    >
    > /* Example 1 */
    >
    > /* func.c */
    >
    > int swap(int a, int b)
    > {
    > a = b;
    > return a;
    > }


    Given this implementation, I think the name 'assign' would have been
    better for this function (same goes for the other examples).

    This function uses 'Pass by Value', and therefor any changes you make to
    a and b will be discarded as soon as you leave the function.

    >
    > /* main.c */
    >
    > int b =1;
    > int c = 2;
    >
    > int main(void)
    > {
    >
    > swap(b,c);
    > printf("%d",c);
    > return 0;
    > }
    >
    > BTW in my example of func.c and main.c here it doesn't seem to matter
    > if I make b, c global variables or local. In writing C how do I best
    > decide if I should make variables global or local, or if it won't
    > affect the purpose of the code should I not care?


    The default should be to use local variables.
    The advantage of local variables is that they are only visible within
    the block where they are declared. This means that in different
    (non-nested) blocks, you can re-use the same name for different
    purposes.

    Global variables should be avoided as much as possible. Use them only
    when there is no reasonable alternative and even then you should prefer
    to declare them as 'static', which will limit their visibility to the
    current source file.

    >
    > /* Example 2 */
    >
    > /* func2.c */
    >
    > int swap(int &a, int &b)


    This is a syntax error in C.

    <snip>
    > /* Example 3 */
    >
    > /* func3.c */
    >
    > int swap(int *a, int *b)
    > {
    > *a = *b;
    > return *a;
    > }


    This function uses 'Pass by Address'.
    Changes to a and b themselves will not be visible or preserved outside
    the function, but changes to *a or *b are visible and preserved.

    >
    > /* main3.c */
    >
    > int *b =1;
    > int *c = 2;


    These two lines should generate a loud complaint from the compiler.
    For this example, it is best to declare b and c the same as in example 1
    int b =1;
    int c = 2;

    >
    > int main(void)
    > {
    >
    > swap(*b,*c);


    This is the wrong syntax for calling the function.
    You need to pass the address of b and c, so you call the function like
    this:
    swap(&b, &c);

    > printf("%d",&c);


    This should just be:
    printf("%d", c);

    But note that the function swap() does not actually modify its second
    argument, so you will see no change here.

    > return 0;
    > }


    A more useful illustration of 'Pass by Value and 'Pass by Address' would
    be this:

    #include <stdio.h>

    void swap_value(int lhs, int rhs)
    {
    int temp;

    printf("Inside swap_value(in): lhs = %d, rhs = %d\n", lhs, rhs);
    temp = lhs;
    lhs = rhs;
    rhs = temp;
    printf("Inside swap_value(out): lhs = %d, rhs = %d\n", lhs, rhs);
    }

    void swap_address(int* lhs, int* rhs)
    {
    int temp;

    printf("Inside swap_address(in): *lhs = %d, *rhs = %d\n", *lhs, *rhs);
    temp = *lhs;
    *lhs = *rhs;
    *rhs = temp;
    printf("Inside swap_address(out): *lhs = %d, *rhs = %d\n", *lhs,
    *rhs);
    }

    int main()
    {
    int a;
    int b;

    a = 1;
    b = 42;
    printf("Before swap_value(a,b): a = %d, b = %d\n", a, b);
    swap_value(a,b);
    printf("After swap_value(a,b): a = %d, b = %d\n", a, b);

    a = 1;
    b = 42;
    printf("Before swap_address(a,b): a = %d, b = %d\n", a, b);
    swap_address(a,b);
    printf("After swap_address(a,b): a = %d, b = %d\n", a, b);

    return 0;
    }

    >
    > PS: I'm learning about closures in Lisp and they seem nifty, but I
    > read C doesn't have them. Or is this not quite true?


    C does indeed not have closures.

    >
    > Lisp 9000


    Bart v Ingen Schenau
    --
    a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
    c.l.c FAQ: http://c-faq.com/
    c.l.c++ FAQ: http://www.parashift.com/c -faq-lite/
     
    Bart van Ingen Schenau, Sep 15, 2007
    #4
  5. "" <> writes:
    > I've read that C allows two ways to pass information between
    > functions:
    >
    > o Pass by Value
    > o Pass by Reference
    >
    > I was talking to some C programmers and they told me there is no such
    > thing as pass by reference in C since you are just passing an address
    > (or a pointer value address I guess?). So I was wondering is this
    > correct?


    Yes and no.

    C does not have pass-by-reference as a built-in language feature. All
    function arguments are passed by value. That's the most important
    thing to remember.

    But it's easy to *emulate* pass-by-reference by passing pointers (the
    pointers are passed by value of course) -- just as you can emulate
    linked lists using structs and pointers.

    C doesn't have pass-by-reference, but that doesn't mean your C program
    can't use pass-by-reference (or at least the equivalent of
    pass-by-reference).

    [...]

    > /* Example 1 */
    >
    > /* func.c */
    >
    > int swap(int a, int b)
    > {
    > a = b;
    > return a;
    > }
    >
    > /* main.c */
    >
    > int b =1;
    > int c = 2;
    >
    > int main(void)
    > {
    >
    > swap(b,c);
    > printf("%d",c);
    > return 0;
    > }


    As you've seen, this doesn't work. But your swap() function doesn't
    even *try* to swap its two arguments; Flash Gordon already covered
    that. Since you're calling printf, you *must* have
    #include <stdio.h>
    at the top of your program. If your compiler doesn't warn you about
    this, crank up the warning level. And you should print a '\n' at the
    end of your program's output.

    If you want to test whether a swap function works, you need to print
    *both* values.

    As a matter of style, your variable names are poorly chosen. You use
    'a' and 'b' as the parameter names for swap(), but you use 'b' and 'c'
    as the names of the variables whose values you pass to it. That's
    perfectly legal (names in different scopes don't have to be distinct),
    but it's confusing.

    [...]

    > /* Example 2 */
    >
    > /* func2.c */
    >
    > int swap(int &a, int &b)

    [snip]

    This appears to be C++, not C. (C++ has a feature called "references"
    that C does not.) If you want to program in C, figure out how to make
    your compiler act as a C compiler.

    > /* Example 3 */
    >
    > /* func3.c */
    >
    > int swap(int *a, int *b)
    > {
    > *a = *b;
    > return *a;
    > }
    >
    > /* main3.c */
    >
    > int *b =1;
    > int *c = 2;
    >
    > int main(void)
    > {
    >
    > swap(*b,*c);
    > printf("%d",&c);
    > return 0;
    > }

    [...]

    There are a number of serious errors in this code. Either your
    compiler isn't telling you about them (in that case, you need to turn
    up its diagnostic level), it's giving you warning messages and you're
    ignoring them.

    For example,
    int *b = 1;
    attempts to assign an int value to an int* variable. This is illegal
    (more precisely it's a "constraint violation", and any conforming
    compiler is required to complain about it).

    Learn how to invoke your compiler so that (a) it compiles C, not C++,
    and (b) so that it complains about as many errors in your code as
    possible -- and pay close attention to any messages it produces, even
    if they're just warnings.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 15, 2007
    #5
  6. In article <>,
    Bart van Ingen Schenau <> wrote:

    >You could also argue that C only has 'Pass by Value', because if you are
    >passing a pointer to something, then it is the value of the pointer
    >that gets passed.


    I think this is the clearest way to describe it. After all, if you
    assign to the (pointer) value in the called function, it doesn't
    affect anything in the caller. You have to explicitly dereference
    the passed it to get the effect of call-by-reference.

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, Sep 15, 2007
    #6
  7. Joe Wright Guest

    Keith Thompson wrote:
    > "" <> writes:
    >> I've read that C allows two ways to pass information between
    >> functions:
    >>
    >> o Pass by Value
    >> o Pass by Reference
    >>
    >> I was talking to some C programmers and they told me there is no such
    >> thing as pass by reference in C since you are just passing an address
    >> (or a pointer value address I guess?). So I was wondering is this
    >> correct?

    >
    > Yes and no.
    >
    > C does not have pass-by-reference as a built-in language feature. All
    > function arguments are passed by value. That's the most important
    > thing to remember.
    >
    > But it's easy to *emulate* pass-by-reference by passing pointers (the
    > pointers are passed by value of course) -- just as you can emulate
    > linked lists using structs and pointers.
    >
    > C doesn't have pass-by-reference, but that doesn't mean your C program
    > can't use pass-by-reference (or at least the equivalent of
    > pass-by-reference).
    >
    > [much snippage]


    Pass-by-reference is the devil's spawn. In C++ it has its own syntax and
    can be 'seen' at least. 11 years ago, in a land far away, I was
    sentenced to maintain someone else's program, written in dBASEIV.

    Three main storage classes of memory variables are PUBLIC, PRIVATE and
    LOCAL. I was already a C programmer and PUBLIC simply meant file-scope
    to me. Likewise, LOCAL was auto within a function block. This PRIVATE
    thing was new and different. It is also the default storage class.

    The effect of PRIVATE is to have calls to subroutines carry PRIVATE
    variables with it without cluttering up the argument list.

    a = 2
    b = 4
    c = 8

    d = foo()
    ? d

    func foo()
    return a + b + c
    endfunc

    In the xBASE languages, ? is the print command and executing the above
    will produce 14 on the console.

    But PRIVATE has also the reference aspect like this..

    a = 2
    foo(a)
    ? a

    func foo(x)
    x = 9
    return

    The parameter x in foo is a reference to variable a in the caller. The
    '? a' line will print 9. I don't remember anymore how long it took me to
    figure that one out but more than a few hours.

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Sep 18, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jerry
    Replies:
    20
    Views:
    8,007
    Roedy Green
    Sep 9, 2005
  2. blufox
    Replies:
    2
    Views:
    582
  3. Mr A
    Replies:
    111
    Views:
    2,168
  4. Robert
    Replies:
    10
    Views:
    1,385
    E. Robert Tisdale
    Aug 24, 2005
  5. LuB
    Replies:
    6
    Views:
    469
    Mike Wahler
    Sep 23, 2005
Loading...

Share This Page