Thread: pass by reference .... HELP!!

  1. #1
    Registered User
    Join Date
    Feb 2006
    Posts
    1

    pass by reference .... HELP!!

    I'm a complete noob when it comes to structs!!

    if I had the struct:

    Code:
    #include<iostream>
    using namespace std;
    typedef struct info{
    char name[20];
    int age;
    }Info;
    int main (){
    Info *pInfo = new Info[10];
    int i=0;
    while (i<10){
    cout<<"Name -> ";
    cin>> pInfo[i].name;
    cout<<"Age -> ";
    cin>>pInfo[i].age;
    i++;
    }
    return 0;}
    does anyone no how to search through a struct through call by reference? thanks! Iv bin trying for hours and nothing works i tink i@d embarass myself if i posted what I wrote.

    ps

    Its for an assignment so I only want pointers .. no pun intended ... so I can learn meself

  2. #2
    Registered User
    Join Date
    Mar 2002
    Posts
    125
    I'm not sure what you want to do. The code you posted looks like it'll do what it's supposed to (fill an array of structs with data), with the exception of you not deleting the memory you reserved for the array.
    Also, you should probably replace:
    Code:
    int i=0;
    while (i<10){
      dostuff();
      i++;
    }
    with
    Code:
    for(int i=0; i<10; i++){
      dostuff();
    }
    Just a tad less cluttered and does exactly the same. If you, for some reason, need to check the value of i after the loop is done (for example if there's a chance you exit the loop before it's completely done) you could use
    Code:
    int i;
    for(i=0; i<10; i++){
      dostuff();
    }
    Last edited by Boksha; 02-08-2006 at 12:20 PM.
    Typing stuff in Code::Blocks 8.02, compiling stuff with MinGW 3.4.5.

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    does anyone no how to search through a struct through call by reference
    Call by reference, or passing by reference, refers to the way a function handles an argument that you send the function. Array names are automatically passed by reference, so you just send the array name(no brackets) to the function. The function parameter can be declared as a pointer--in which case, the type will be a pointer to the first element of the array--or the function parameter can be declared as an array. Note that the leftmost dimension of an array is meaningless as far as it's type is concerned, so you don't put anything between the brackets.

  4. #4
    Registered User
    Join Date
    Feb 2006
    Posts
    65
    Quote Originally Posted by 7stud
    Array names are automatically passed by reference, so you just send the array name(no brackets) to the function.
    If arrays were passed by reference, wouldn't this program would print "Hello World!" instead of "Hello Hello" ?
    Code:
    #include <iostream>
    
    using namespace std;
    
    void changeMe(char[]);
    
    int main(void)
    {
        char str[] = "Hello ";
        cout << str;
        changeMe(str);
        cout << str << endl;
    }
    
    void changeMe(char param[])
    {
        param = "World!";
    }
    It would be more correct to say that the pointer to the array is passed by value, which is what actually seems to happen.

  5. #5
    Registered User
    Join Date
    Dec 2005
    Posts
    32
    Code:
    void changeMe(char param[])
    {
        param = "World!";
    }
    I'm not an expert, but I would say that you are just telling the local pointer param to point to the read-only string "World!". This pointer is discarded when the function exits, and since the function doesn't actually do anything, str in main remains unchanged.

    Remember that everything is passed by value, so the changeMe() only gets a copy of the pointer str. If you inside the function want to alter what both str and param points to, use something like strcpy(param, "World!").

    -tretton

  6. #6
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    Quote Originally Posted by Boksha
    Code:
    int i=0;
    while (i<10){
      dostuff();
      i++;
    }
    with
    Code:
    for(int i=0; i<10; i++){
      dostuff();
    }
    I dunno ... the only problem I have with while() things for that kind of operations is that the itterating value has to be reset to 0 every time. other than that .... it only really depends on how you lay out your code for how cluttered it is ... eg:

    Code:
    int i = 0;
    while ( i<var )
    {
       //do stuff
       i++;
    }
    i=0;
    looks fine to me anyways. nice indenting and whatnot go a long way in my opinion.

  7. #7
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    First, try the following modification of your function to see that the array is in fact "passed by reference":
    Code:
    void changeMe(char param[])
    {
        param[0] = 'X';
    }
    As to why, your function:
    Code:
    void changeMe(char param[])
    {
        param = "World!";
    }
    doesn't work they way you expected, you have to understand what "passing by reference" really means. When you really understand pointers and passing by reference, you will understand the truth of tretton's statement:
    Remember that everything is passed by value
    The programming books all lie when they say some arguments are "passed by reference" and others are "passed by value"--because all arguments are really passed by value in that they are all copied.

    If you pass an int to a function, then the int is copied for the function and the function operates on the copy. So any changes the function makes to the copy do not affect the original int back in main(). When you pass a pointer to a function, the pointer is copied as well. However, a pointer is an address and a copy of an address refers to the same location in memory as the original address. So when you pass a pointer to a function, the function can use the copy of the address to change the value at that location in memory. Try this code:
    Code:
    #include <iostream>
    using namespace std;
    
    void changeIt(int* p)
    {
    	cout<<p<<endl;  //006BFDF4
    }
    
    int main()
    {
    	int num = 10;
    	int* ptr = &num;
    	cout<<ptr<<endl;  //006BFDF4
    
    	changeIt(ptr);
    	
    	return 0;
    }
    Since the address stored in ptr in main() is the same address stored in p in changeIt(), the changeIt() function can use p to change the value at that location:
    Code:
    #include <iostream>
    using namespace std;
    
    void changeIt(int* p)
    {
    	cout<<p<<endl;  //006BFDF4
    	*p = 25;
    }
    
    int main()
    {
    	int num = 10;
    	int* ptr = &num;
    	cout<<ptr<<endl;  //006BFDF4
    
    	changeIt(ptr);
    	cout<<num<<endl;  //25
    	
    	return 0;
    }
    It is also important to note that this is pass by value in the full sense--just like when passing an int variable by value to a function, and the function is unable to change the value of the variable back in main(). While the function above is able change the value that ptr points to, the function cannot change ptr itself back in main(), i.e. the function cannot assign a different address to ptr. Here is an example:
    Code:
    #include <iostream>
    using namespace std;
    
    void changeIt(int* p, int& anotherNum)
    {
    	p = &anotherNum;
    	cout<<*p<<endl;  //32
    }
    
    
    int main()
    {
    	int num = 10;
    	int* ptr = &num;
    	
    	int num2 = 32;
    	changeIt(ptr, num2);
    	cout<<*ptr<<endl;  //10
    	
    	return 0;
    }
    That is similar to what is happening in your function. This statement:
    Code:
    #include <iostream>
    
    using namespace std;
    
    void changeMe(char[]);
    
    int main(void)
    {
        char str[] = "Hello ";
        cout << str;
        changeMe(str);
        cout << str << endl;
    }
    
    void changeMe(char param[])
    {
        param = "World!";
    }
    says to assign the address of the string "World!" to param. param is a copy of str and anything you assign it has no effect on str back in main(). In fact, an array name is const, which means it cannot be made to refer to any other location in memory, and this produces an error:
    Code:
    char str[] = "Hello ";
    str = "World!";  //compiler error
    so param and str cannot be the same thing or you would get a compiler error.

    In conclusion, this function:
    Code:
    void changeMe(char param[])
    {
        param[0] = 'X';
    }
    uses the address stored in param to change the value at that address in memory. Since str back in main() also points to that value, it can see the changes. Both str and param point to the same value, so when one of them is used to change the value, the other one can see that change.

    And this function:
    Code:
    void changeMe(char param[])
    {
        param = "World!";
    }
    assigns a new address to param, overwriting the address currently stored in param, which has no effect on the address stored in str back in main(). Subsequently, param and str point to two different values.
    Last edited by 7stud; 02-09-2006 at 06:00 AM.

  8. #8
    Registered User
    Join Date
    Feb 2006
    Posts
    65
    Ah, so arrays are not passed by reference, but a pointer to the array is passed by value?

    Remember that everything is passed by value
    But I remember reading that in C++, unlike in C, you can also use pass-by-reference? With arrays apparently not, but with some other types maybe?

  9. #9
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    lol. I suggest you read my post again. This was the first sentence:
    First, try the following modification of your function to see that the array is in fact "passed by reference":
    ---
    But I remember reading that in C++, unlike in C, you can also use pass-by-reference?
    Did you see this:
    The programming books all lie when they say some arguments are "passed by reference" and others are "passed by value"--because all arguments are really passed by value in that they are all copied.
    Either you live in a world where there are two ways to pass arguments to a function: passing by reference and passing by value, and in that world arrays and pointers are always passed by reference; or as in the Matrix, you wake up to the real world, and you recognize that everything is passed exactly the same way: by value, and all arguments are copied for a function.

    I prefer the latter because it's a much simpler world to live in: the rule is all arguments are copied.
    Last edited by 7stud; 02-09-2006 at 07:30 AM.

  10. #10
    Registered User
    Join Date
    Feb 2006
    Posts
    65
    Hmmmm, I checked my sources. I was referring to something like this:
    Code:
    #include <iostream>
    
    using namespace std;
    
    void pass_by_value(string);
    void pass_by_reference(string&);
    
    int main(void)
    {
        string str = "Hello ";
        cout << "Passing by value: " << str;
        pass_by_value(str);
        cout << str << endl;
        
        cout << "Passing by reference: " << str;
        pass_by_reference(str);
        cout << str << endl;
    }
    
    void pass_by_value(string param)
    {
        param = "World!";
    }
    
    void pass_by_reference(string &param)
    {
        param = "World!";
    }
    The output of the program is
    Passing by value: Hello Hello
    Passing by reference: Hello World!
    If str was passed by value to "pass_by_reference" its value would have been copied like you say, and the function could have no effect on the variable in the main function. So by this example it would seem that there are two ways to pass arguments to functions.

    Do you see "passing by reference" as a special case of passing by value?

  11. #11
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    In your pass by reference function, you are actually passing an address to the function. The compiler takes the address of str and sticks it in param. A reference is like a const pointer and since param is a reference type, it stores an address. The syntax of references hides all that. The statement param="World" says to copy "World" into the memory location that param points to. Since param points to str, str is changed.

    Your pass by reference function actually operates similarly to the following:
    Code:
    #include <iostream>
    using namespace std;
    
    void changeIt(int* const p)
    {
    	*p = 32;
    }
    
    int main()
    {
    	int num = 10;
    	int* const ptr = &num;  
    	
            changeIt(ptr);
    	cout<<num<<endl;
    	
    	return 0;
    }
    Last edited by 7stud; 02-09-2006 at 07:55 AM.

  12. #12
    Registered User
    Join Date
    Feb 2006
    Posts
    65
    I see. And how does this differ from the computer science definition of "passing by reference" ?

    First, try the following modification of your function to see that the array is in fact "passed by reference":
    That by the way does not account for passing by reference. It, like you say, accounts for passing a pointer by value. Passing by reference as per the definition is very different.

    The programming books all lie when they say some arguments are "passed by reference" and others are "passed by value"--because all arguments are really passed by value in that they are all copied.
    If all arguments were "passed by value in that they are all copied" then the output of my program above would be different. Both calls are of the form function(str). In pass-by-value, the value of str would have to be copied and then the copy would be passed, yielding identical results. No?

    You can argue that "behind the scenes the compiler handles pass-by-reference by generating code that pushes on the stack a copy of of a memory address" but IMHO a programmer does or should not need to know how a compiler generates code (though admittedly sometimes it helps). From the programmer's perspective one function is using pass-by-value and the other one is using pass-by-reference.

  13. #13
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    If all arguments were "passed by value in that they are all copied" then the output of my program above would be different. Both calls are of the form function(str)
    Fair enough. But doesn't str look something like this:

    0457DB8
    str
    Hello

    and if so, what is str actually? In one case "Hello" gets assigned to the parameter variable and in another case 0457DB8 gets assigned to the parameter variable. Did one function get a copy of str but the other one didn't? Which one did and which one didn't?
    Last edited by 7stud; 02-09-2006 at 08:59 AM.

  14. #14
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    This is how I rationalize things. With pass-by-reference, a pointer is passed (which itself is passed by value/copy). The difference with pass-by-reference is that the extra syntax of dereferencing the pointer within the function is taken care of for you by the compiler. This:

    Code:
    void func(string & str)
    {
        str = "World";
    }
    Can be considered as this:
    Code:
    void func(string * str)
    {
        *str = "World";
    }
    The only difference between these two (besides the */& in the argument list) is the use of the dereferencing operator (*) in the functions one line of code. Using the reference just hides that dereferencing step from you making your life a little bit easier by not having to slave away all day at a hot keyboard by typing that extra 1 character (in this example). And, since the pointer is passed by value/copy, it should not take much of a leap in imagination to see that this means the reference is actually passed by value/copy as well since it is a pointer (but with simplified syntax in terms of its usage throughout the function).

    [edit]
    If all arguments were "passed by value in that they are all copied" then the output of my program above would be different. Both calls are of the form function(str).
    But they are not, one is of the form function(string) and the other is essentially of the form function(string*).
    [/edit]
    Last edited by hk_mp5kpdw; 02-09-2006 at 08:56 AM.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  15. #15
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    If all arguments were "passed by value in that they are all copied" then the output of my program above would be different. Both calls are of the form function(str).
    But they are not, one is of the form function(string) and the other is essentially of the form function(string*)
    I understand joni's point. Both functions are called the same way. So the point is: if all arguments are copied and two functions are called with the same argument, yet the two functions end up with two different things, then there is something dissimilar about the way the argument is being passed.

    If I had read joni's posts more carefully from the beginning, I would have recognized that joni understood that pointers are passed by value, and joni was arguing something else.
    Last edited by 7stud; 02-09-2006 at 09:09 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pass by reference
    By jrice528 in forum C++ Programming
    Replies: 4
    Last Post: 10-30-2007, 01:02 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. C OpenGL Compiler Error?
    By Matt3000 in forum C Programming
    Replies: 12
    Last Post: 07-07-2006, 04:42 PM
  4. how can i pass by reference by "malloc 2d array"?
    By Mathsniper in forum C Programming
    Replies: 10
    Last Post: 05-22-2005, 02:23 PM
  5. Ask about function parameters and pass a reference.
    By ooosawaddee3 in forum C++ Programming
    Replies: 1
    Last Post: 11-04-2002, 12:14 PM