pass by reference is valid?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • lisp9000@gmail.com

    #1

    pass by reference is valid?

    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

  • Flash Gordon

    #2
    Re: pass by reference is valid?

    lisp9000@gmail. com 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

    Comment

    • Army1987

      #3
      Re: pass by reference is valid?

      On Sat, 15 Sep 2007 07:55:47 +0000, lisp9000@gmail. com 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

      Comment

      • Keith Thompson

        #4
        Re: pass by reference is valid?

        "lisp9000@gmail .com" <lisp9000@gmail .comwrites:
        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_Keit h) kst-u@mib.org <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"

        Comment

        • Bart van Ingen Schenau

          #5
          Re: pass by reference is valid?

          lisp9000@gmail. com 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(in t* 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(ou t): *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/

          Comment

          • Richard Tobin

            #6
            Re: pass by reference is valid?

            In article <1715160.8Tihy0 gEb6@ingen.ddns .info>,
            Bart van Ingen Schenau <bart@ingen.ddn s.infowrote:
            >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
            --
            "Considerat ion shall be given to the need for as many as 32 characters
            in some alphabets" - X3.4, 1963.

            Comment

            • Joe Wright

              #7
              Re: pass by reference is valid?

              Keith Thompson wrote:
              "lisp9000@gmail .com" <lisp9000@gmail .comwrites:
              >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 ---

              Comment

              Working...