Thread: Working with functions

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    11

    Working with functions

    I don't know if this is a suitable subforum to talk about the the following
    Suppose we have a function called foo() which receive two arguments foo(a,b) and swap them.

    Code:
    int n1 = 2, n2 = 33;
    // before swap
    print n1, n2;
    foo(n1,n2);
    // after swap
    print n1, n2;
    
    // the function
    foo(a, b) {
     int temp = a;
     a = b;
     b = temp;
    }
    The expected output:
    >> 2 33
    >> 33 2

    Is that right or de we have to work with "pointers"?
    Last edited by themsaman; 03-14-2010 at 06:50 AM. Reason: add notification

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    C always copies parameters - so if you want to change a value of a variable - in any way - you must have the address of the variable. Otherwise, only the *copy* gets changed, and when you return to the calling function, that copy will be "out of scope" (gone to variable heaven, as it were), in most cases.

    Pointers aren't curses, they're actually a strong benefit, and sending them off on simple functions like this, is a great way to learn to work with them. Don't avoid them - use them, and get very familiar with them.

  3. #3
    Registered User
    Join Date
    Mar 2010
    Posts
    11
    Thanks Adak, I was just wondering how would the function react in the intern using 'copies'. Now, when you say "C always copies parameters..", I assume that other languages have other characteristics than C.

    In PHP has to be something like this:
    PHP Code:
    <?php
      $a 
    2;
      
    $b 3;
      
      
    //before swap
      
    echo $a ' ' $b;
      
    //after swap
      
    foo($a,$b);
      echo 
    "\n" $a ' ' $b;

      function 
    foo( &$p,  &$q){
        
    $tmp $p;
        
    $p $q;
        
    $q $tmp;
      }

    ?>
    Let's do the same thing in C (I used Dev-C++ to write this code):

    Code:
    #include <stdio.h>
    #include <stdlib.h>
      
      void foo(int*, int*);
    
      int main(int argc, char *argv[]){
          
          int a = 2;
          int b = 33;
          int *p, *q;
          p = &a;
          q = &b;
         
          printf("%d, %d\n",*p,*q);
          foo(p, q); 
          printf("%d, %d\n",*p,*q);
                  
          system("PAUSE");	
          return 0;
      }
      
       void foo(int *a, int *b){
               int tmp = *a;
               *a = *b;
               *b = tmp;
       }
    Or

    Code:
      
      void foo(int*, int*);
    
      int main(int argc, char *argv[]){
          
          int a = 2;
          int b = 33;
         
          printf("%d, %d\n",a,b);
          foo(&a, &b); 
          printf("%d, %d\n",a,b);
                  
          system("PAUSE");	
          return 0;
      }
      
       void foo(int *a, int *b){
               int tmp = *a;
               *a = *b;
               *b = tmp;
       }

    In C is more difficult to understand what's happening!!

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by themsaman
    In C is more difficult to understand what's happening!!
    Not really. It is just a matter of understanding how pointers work. Speaking of PHP, consider:
    Code:
    <?php
    class X
    {
        public $x;
    
        public function __construct($x)
        {
            $this->x = $x;
        }
    }
    
    function foo($a, $b)
    {
        $t = $a->x;
        $a->x = $b->x;
        $b->x = $t;
    }
    
    $c = new X(1);
    $d = new X(2);
    foo($c, $d);
    echo $c->x, ', ', $d->x;
    You see, object references in PHP 5 behave like C pointers in this way.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Mar 2010
    Posts
    11
    It is very easy when working with objects in .NET, Java or PHP. That's true and I don't doubt about that, but that doesn't make pointers of C easier to understand.

    If I do the following in C:
    Code:
    void foo(int *a, int *b){
               int tmp = a;
               a = b;
               b = tmp;
       }
    Then the swap won't take a place at all.

    Or if I do this:
    Code:
     //...
          printf("%d, %d\n",a,b);
          foo(a, b); 
          printf("%d, %d\n",a,b);
          //....
      }
    Or this:
    Code:
     //...
          printf("%d, %d\n",a,b);
          foo(*a, *b); 
          printf("%d, %d\n",a,b);
          //....
      }
    You see what I mean?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    No, I do not see what you mean. Any decent C compiler will complain for any of the three examples that you cited, especially if you compile at a suitably high warning level. Furthermore, mistakes can happen with any programming language.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    As a side note, I recommend that instead of...
    void foo(int*, int*);
    ...you do...
    void foo(int* a, int* b);
    For more information, refer to SourceForge.net: Do not remove parameter names - cpwiki
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    11
    Why?
    int *p is the same as int* p
    Or is that a kind of habit of writing pointers in C?

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, the names of the parameters were missing.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Mar 2010
    Posts
    11
    OK, but the program is working in both cases.
    I am debugging it and I get sometimes a bizarre results !!

    I watch the variable b which gives at the start b = 58

    I use Dev-C++ to debug!

    Code:
    #include <stdio.h>
    #include <stdlib.h>
      
      void foo(int* p, int* q);
    
      
      int main(int argc, char *argv[]){
          
          int a = 2;
          int b = 33;
         
          printf("%d, %d\n",a,b);
          foo(&a, &b);
          printf("%d, %d\n",&a,&b);
                     
          system("PAUSE");	
          return 0;
      }
      
      void foo(int* p, int* q){
               int tmp = *p;
               *p = *q;
               *q = tmp;
       }

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by themsaman
    I watch the variable b which gives at the start b = 58
    You can ignore the garbage until you are actually at or past the point where b has been set to some initial value.

    This:
    Code:
    printf("%d, %d\n",&a,&b);
    should be:
    Code:
    printf("%d, %d\n", a, b);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Mar 2010
    Posts
    11

    Talking debug and getchar();

    Code:
    printf("%d, %d\n",&a,&b);
    No, I did that explicitly because I wanted to see how pointers work with adresses in the memory.

    Code:
    #include <stdio.h>
    void swap (int *a, int *b); // prototype
    int main()
    {
        int n1, n2;
        printf( "Insert number 1.\n" );
        scanf("%d", &n1);
        printf( "Insert number 2.\n" );
        scanf("%d", &n2);
        //before swap
        printf("Inserted numbers: %d located in %d and %d loctaed in %d\n",n1,&n1,n2,&n2);
        swap(&n1, &n2);
        //after swap
        printf("Inserted numbers: %d located in %d and %d loctaed in %d\n",n1,&n1,n2,&n2);
        getchar();
        getchar();
        return 0;
    }
    void swap(int *x, int *y){
      int tmp = *x;
      *x = *y;
      *y = tmp;
    }
    The swap functions doesn't change the addresses but it changes the pointers, so x points to the address of y and vice versa. That's what I see.

    Ok, I did not know why I got the number n1 = 2 at the start of debugging. I have been using Java and PHP for a years but this C seems to be a different product :-).

    I have a question about this:
    Code:
        getchar();
        getchar();
    If I don't do that I don't get anything on the screen, I know why I used getchar(); but I don't know what's exactly happening in there.

  13. #13
    Registered User
    Join Date
    Mar 2010
    Posts
    11
    Now, If I write this:
    Code:
    char c = getchar();
        printf("%d",(int)c);
        getchar();
        getchar();
        return 0;
    I get here number 10 which is (according ascii) new line.
    What happened? Did the getchar() read this new line:
    printf("Inserted numbers: %d located in %d and %d loctaed in %d\n",n1,&n1,n2,&n2);

    ?

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by themsaman View Post
    Code:
    printf("%d, %d\n",&a,&b);
    No, I did that explicitly because I wanted to see how pointers work with adresses in the memory.
    Printing addresses with %d is undefined.
    %d signals you're passing an unsigned int. But, for example, on 64-bit Windows, the size of an unsigned int is not the same size as a memory address (32 bits vs 64 bits). So you see why it's bad. Use %p instead and cast to void*.

    The swap functions doesn't change the addresses but it changes the pointers, so x points to the address of y and vice versa. That's what I see.
    It doesn't. It only changes the values stored in the memory regions occupied by x and y.

    Ok, I did not know why I got the number n1 = 2 at the start of debugging. I have been using Java and PHP for a years but this C seems to be a different product :-).
    Unlike Java, C does not (unnecessarily) initialize variables to some predefined value.
    So before you actually create and initialize them, they contain junk.
    I have a question about this:
    Code:
        getchar();
        getchar();
    If I don't do that I don't get anything on the screen, I know why I used getchar(); but I don't know what's exactly happening in there.
    scanf never reads the newline (\n) in the input buffer that comes from you pressing enter. So the first getchar() reads it from the input and the second stalls for more input.

    Quote Originally Posted by themsaman View Post
    Now, If I write this:
    Code:
    char c = getchar();
        printf("%d",(int)c);
        getchar();
        getchar();
        return 0;
    I get here number 10 which is (according ascii) new line.
    What happened? Did the getchar() read this new line:
    printf("Inserted numbers: %d located in %d and %d loctaed in %d\n",n1,&n1,n2,&n2);

    ?
    A leftover from the input buffer. See previous reply.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Jul 2009
    Location
    Croatia
    Posts
    272
    Unlike Java, C does not (unnecessarily) initialize variables to some predefined value.
    So before you actually create and initialize them, they contain junk.
    Exception are global variables. They're always set to 0.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Static functions.... why?
    By patricio2626 in forum C++ Programming
    Replies: 4
    Last Post: 04-02-2007, 08:06 PM
  2. Static member functions more efficient?
    By drrngrvy in forum C++ Programming
    Replies: 6
    Last Post: 06-16-2006, 07:07 AM
  3. Functions and Classes - What did I do wrong?
    By redmage in forum C++ Programming
    Replies: 5
    Last Post: 04-11-2005, 11:50 AM
  4. calling functions within functions
    By edd1986 in forum C Programming
    Replies: 3
    Last Post: 03-29-2005, 03:35 AM
  5. Functions are not working
    By founder247184 in forum C++ Programming
    Replies: 0
    Last Post: 11-29-2002, 04:00 PM