Thread: pass by reference question

  1. #1
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681

    pass by reference question

    I know C doesn't have a "true" pass by reference, but I also know it can be simulated by using pointers.
    While it works I want to know if the following would be the best way to pass a variable recieved by reference to another routine by refence. (subroutine1 passes var x by ref to subroutine2 which then passes to subroutine3 by ref).

    Code:
    void sub1(int x)
    {
      sub2(&x);
    }
    
    void sub2(int* x);
    {
      sub3(&*x);
    }
    
    void sub3(int* x);
    {
    }
    I know the code I posted does jack squat but I'm more interested in making sure that the way I did the passing is proper. (real code does some addition and printf to show that it does work)

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    That won't work. Pointers are the only way.


    Here:

    Code:
    void sub1(int x)
    {
      sub2(&x);
    }
    ...viewed from within the function, we're just being handed a temporary object that was created from the stack. So all you're passing to sub2 is the address of the temporary.

    Code:
    void sub2(int* x);
    {
      sub3(&*x);
    }
    ...doesn't matter if you do:

    &(*(&(*(&(*x)))))


    The end result is still the same temporary object you started with.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Not sure that I'm following ya Sebastiani. Here is the actual code I used to test (minus the other combos).

    Code:
    #include <stdio.h>
    
    void print(int, char*, int, int);
    
    void test7(int*);
    void test8(int*);
    
    int main (void)
    {
    	int x=4;
    	printf("\nR -> R\t%d\n",x);
    	test7(&x);
    	printf("At end: %d\n", x);
    }
    
    void print(int a, char* s, int b, int c)
    {
    	printf("test%d %s test%d : %d\n", a, s, b, c);
    }
    
    void test7(int* x)
    {
    	print(7, "Before Inc", 7, (int) *x);
    	++(*x);
    	print(7, "Before", 8, (int) *x);
    	test8(&*x);
    	print(7, "After", 8, (int) *x);
    }
    
    void test8(int* x)
    {
    	print(8, "Before Inc", 8, (int) *x);
    	++(*x);
    	print(8, "After Inc", 8, (int) *x);
    }
    Which gave me the output of:
    Code:
    R -> R  4
    test7 Before Inc test7 : 4
    test7 Before test8 : 5
    test8 Before Inc test8 : 5
    test8 After Inc test8 : 6
    test7 After test8 : 6
    At end: 6
    This to me seems to indicate that it works.
    I've tried test8(&x) and test(*x) and I always get a compile error.

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    I'm truly confused. Of course by dereferencing a pointer you'll alter the value at the other end. My point was, given:

    Code:
    void sub1(int x);
    void sub2(int * x);
    void sub3(int * x);
    
    void sub1(int x)
    {
     printf("%x\n", &x);
     sub2(&x);
    }
    
    void sub2(int * x)
    {
     printf("%x\n", x);
     sub3(&*x);
    }
    
    void sub3(int * x)
    {
     printf("%x\n", x);
    }
    
    
    int
     main(int , char ** argv)
    {
     int x, * p = &x;
     printf("%x\n", &x);
     printf("%x\n", p);
     sub1(x);
    }

    The output would be something like:

    76fde4
    76fde4
    76fdc0
    76fdc0
    76fdc0


    However, given:

    Code:
    void sub1(int * x);
    void sub2(int * x);
    void sub3(int * x);
    
    void sub1(int * x)
    {
     printf("%x\n", x);
     sub2(x);
    }
    
    void sub2(int * x)
    {
     printf("%x\n", x);
     sub3(x);
    }
    
    void sub3(int * x)
    {
     printf("%x\n", x);
    }
    
    
    int
     main(int , char ** argv)
    {
     int x, * p = &x;
     printf("%x\n", &x);
     printf("%x\n", p);
     sub1(&x);
    }

    the output would be something like:


    76fde4
    76fde4
    76fde4
    76fde4
    76fde4


    In other words, no matter how many functions pass a pointer, the value (the pointer, that is) remains unchanged. That's all.
    Last edited by Sebastiani; 11-30-2003 at 01:05 AM.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Registered User
    Join Date
    Nov 2003
    Posts
    46

    This works for me

    The following works for me. I changed the variable name in sub2 and sub3 from x to xp. This reflects the fact that it is actually an integer pointer that points to where x is stored. I find this type of naming always helps me.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    void sub3(int* xp)
    {
      printf("4) in sub3 *xp = %d\n",*xp);  
      *xp=6;
      printf("5) in sub3 *xp = %d\n",*xp);  
    }
    
    void sub2(int* xp)
    {
    
      printf("3) in sub2 *xp = %d\n",*xp);
      sub3(xp);
      printf("6) in sub2 *xp = %d\n",*xp);
    }
    
    void sub1(int x)
    {
      printf("2) in sub1 x = %d\n",x);
      sub2(&x);
      printf("7) in sub1 x = %d\n",x);
    }
    
    int main(void)
    {
      int x = 5;
      
      printf("1) in main x = %d\n",x);
      sub1(x);
      printf("8) in main x = %d\n",x);
        
      system("PAUSE");	
      return 0;
    }

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I've tried test8(&x) and test(*x) and I always get a compile error.
    This is because neither &x nor *x are a pointer to int. &x is a pointer to a pointer to int, *x is an int. The function you want to pass to expects a pointer to int, so you just need to pass x. &*x is exactly the same as passing x (except a little more obfuscated).
    My best code is written with the delete key.

  7. #7
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Thanks Prelude! I understand it clearly now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Speed test result
    By audinue in forum C Programming
    Replies: 4
    Last Post: 07-07-2008, 05:18 AM
  3. Textbox
    By maxorator in forum Windows Programming
    Replies: 20
    Last Post: 09-25-2005, 10:04 AM
  4. How to: Use OpenGL with Jgrasp
    By Pickels in forum Game Programming
    Replies: 3
    Last Post: 08-30-2005, 10:37 AM
  5. pass be reference versus pass by value
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 08-01-2002, 01:03 PM