C++ references and references parameters - c++

Please look at the code snippet below - I have declared 3 functions (i.e. 1 passing an int and the others passing reference to an int). After executing the program I found that the value of "count" variable after calling function (tripleByReference) has not been changed to reflect its triple (count is still equal to 5). However calling function (tripleByReferenceVoid) modifies the variable but this is due to the fact that changes occurred directly to the variable (count).
I understand that with pass by reference, the caller gives the called function the ability to access the caller's data directly and modify it but that could not be achieved by passing the variable to function (tripleByReference) - Please help me to understand this.
#include <iostream>
using namespace std;
/* function Prototypes */
int tripleByValue(int);
int tripleByReference(int &);
void tripleByReferenceVoid(int &);
int main(void)
{
int count = 5;
//call by value
cout << "Value of count before passing by value is: " << count << endl;
cout << "Passing " << count << " by value, output is: "
<< tripleByValue(count) << endl;
cout << "Value of count after passing by value is: " << count << endl;
//call by reference - using int tripleByReference
cout << "\n\nValue of count before passing by reference is: " << count << endl;
cout << "Passing " << count << " by reference, output is: "
<< tripleByReference(count) << endl;
cout << "Value of count after passing by reference is: " << count << endl;
//call by reference - using void tripleByReference
tripleByReferenceVoid(count);
cout << "\n\nValue of count after passing by reference is: " << count << endl;
cout << endl;
system("PAUSE");
return 0;
}//end main
int tripleByValue (int count) {
int result = count * count * count;
return result;
}//end tirpleByValue function
int tripleByReference(int &count) {
int result = count * count * count;
return result; //perform calcs
}//end tripleByReference function
void tripleByReferenceVoid(int &count) {
count *= count * count;
}//end tripleByReference function
Thank you.

tripleByReference doesn't change the value of count because you never assign to it. You are returning the value instead.
tripleByReferenceVoid is different. You are assigning to it (count *= ...) and that is why these changes are reflected.

In your function tripleByReference you are not even attempting to modify the value of count, while in your function tripleByReferenceVoid you are explicitly modifying count. Hence the obvious and expected effect: the latter function modifies count, the former doesn't. I.e. these functions do exactly what and only what you explicitly and consciously asked them to do.
Questions like this one is difficult to answer because it is virtually impossible to understand what made you to ask it. You seem to be puzzled by the fact that the behavior of these two functions is different. But why does it puzzle you, when you yourself explicitly wrote them to be different in that specific regard?

Related

My recursive display function is not going to the next value of the array

I have a recursive display function, meant to go through the values of array b and print the details. My function is successful in looping the correct amount of times, but only prints out the value at index 0. For example, if I have 3 books, it prints out the first book 3 times and is not going to the other values. I am a beginner programmer and I believe I am missing something very simple or obvious, but any help is appreciated.
void displayBooks(int n)
{
// Write the code below
if (n >= currentCount) {
return;
}
else {
cout << "Name: " << b->getName() << "\n";
cout << "Name of Book Author: " << b->getAuthor() << "\n";
cout << "Publication Year: " << b->getYearOfPublication() << "\n";
cout << "ID: " << b->getID() << "\n";
displayBooks(n + 1);
}
}
This is the function itself, however I can't show the complete program since it is a lot of code with multiple files. When the function is first called as displayBooks(0) in a switch case.
I believe that you are not printing out each index of the "b" variable you need to access the index of each one. You need to have b as an array of pointers then access the index of that variable like b[n]->someProperty();
You can create the array like this:
Obj* b[HOWMANY];

The actual and formal parameters of the array use the same block address, while the variables use different addresses

When using the address transfer of function, View address blocks of formal parameters and actual parameters, I find that the arguments and formal parameters of array share one address block, while the arguments and formal parameters of variables use two address block. What is the reason?
The code is as follows:
#include<iostream>
using namespace std;
void test(int *i,int * arr) {
cout << &i << endl;
cout << arr << endl;
}
int main() {
int i = 1, arr[2] = {1,2};
cout << &i << endl;
test(&i, arr);
cout << arr << endl;
system("pause");
return 0;
}
And this is the output:
0000008986B6FC54
0000008986B6FC30
0000008986B6FC78 //Arrays use the same space
0000008986B6FC78
You are passing pointers to the functions. The value of the pointers are not modified, ie in the function they point to the same objects as they do in main.
However, you are not printing what you think you print:
void test(int *i,int * arr) {
cout << &i << endl;
cout << arr << endl;
}
The pointer i gets the parameter &i (the i from main). Hence printing i in main will yield the same value as printing i in test. However, you are printing the adress of i in the function not the value of it. If you change your code to:
void test(int *i,int * arr) {
cout << &i << endl;
cout << i << endl;
cout << arr << endl;
}
You will notice the difference. I suggest you to rename at least one of the is in your code, because using same name for different entities can and does cause confusion. The i in test holds the value of the address of the i in main. That does not mean that they are the same, but rather i in test has the same value as &i in main.
In short: &i == &i but you expect &(&i) to be the same as &i.
There is no difference between passing a pointer to the int or passing a pointer to the first element of the array. From the point of view of the function they are both just pointers to int.
Note that test prints the value of arr but the location of i.
In test, &i is the location of its argument i.
That argument's value is the location of the i in main.
You will see this if you print i instead of &i.
arr, on the other hand, is implicitly converted into a pointer to its first element, and you are both passing &arr[0] to test to print, and printing &arr[0] in main.
Here is the same thing with explicit conversions and without using a function:
int main() {
int i = 1, arr[2] = {1,2};
cout << &i << endl;
// Create the "argument"...
int *p = &i;
// These two lines are 'test'...
cout << &p << endl;
cout << &arr[0] << endl;
// and this is after the function call.
cout << &arr[0] << endl;
}

Trying to understand passing by reference C++ [duplicate]

This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 2 years ago.
I understand the basic difference between the passing by value and passing by reference. Passing by value means that you pass values as function arguments and passing by reference means that you just simply pass the variable.
What I don't get is how exactly works. Here is my example.
#include <iostream>
// Initializing Functions
void swap(int &first, int &second);
void write_and_prompt();
int main()
{
int num1 {30};
int num2 {185};
std::cout << "The original value of num1 is: " << num1 << '\n';
std::cout << "The original value of num2 is: " << num2 << '\n';
std::cout << "\nSwapping values..." << '\n';
std::cout << "Values have been swapped." << '\n';
// Function for swapping values.
swap(num1, num2);
std::cout << "\nThe value of num1 is: " << num1 << '\n';
std::cout << "The value of num2 is: " << num2 << '\n';
// Function that ends program after users input
write_and_prompt();
} // End of main
// Creating Fucntions
void swap(int &first, int &second)
{
int temp = first;
first = second;
second = temp;
}
void write_and_prompt()
{
std::cout << "\nPress enter to exit the program." << '\n';
std::cin.get();
}
So what I don't understand is when I call the function swap(num1, num2) I'm passing these two variables but in the syntax of the function I have &first, &second.
I thought that I was passing the address of num1 and num2 but then I thought that I would need pointers in the function to be able to work with them plus I would use the address-of operator in front of num1 and num2 instead.
Anyway what I trying to understand is why using the address-of operator(&) makes the function take the variables num1 and num2.
I thought that this operator just gives the address of the variable or maybe I didn't understand it correctly.
You are correct that the unary & operator gives the address of a variable. However, & in function arguments is not the address-of operator--it's marking that particular parameter as being pass-by-reference, which has different semantics than passing around pointers. If you want to pass in pointers, you'd use int *first, int *second, same as declaring a pointer-to-an-integer within a function body.
int & is a reference to int and is different from address-of operator. Your function parameters are references so you don't need to pass address or pointers.

how can a void function be called to the main, if there are no returns?

I wanted to create a function that retrieves all the information from previous functions within the same Class, and prints the values that were returned in the format of a bunch of cout statements, there is nothing for me to return in this PrintStatement() function, so I would create a void function, correct? My issue is in the int main(), I cannot cout a void function.
this is my account header file, and the function piece from my account.cpp file.
class Account {
public:
//Object constructor
Account(char firstName[], char lastName[], char sinNumber[], double balance, int accountType, int transactions);
//Object operations
double DepositAmt(double amount);
double WithdrawAmt(double amount);
void PrintStatement();
double getFinalBalance(double fbal);
string getAccountType();
double getTransactions (double Deposit, double Withdraw);
private:
//Object properties
char firstName[255];
char lastName[255];
char sinNumber[255];
double balance;
int accountType;
int transactions;
};
void Account::PrintStatement()
{
cout << "First Name: " << firstName << endl;
cout << "Last Name: " << lastName << endl;
cout << "SIN Number: " << sinNumber << endl;
cout << "Account Type: " << accountType << endl;
cout << "Final Balance: " << balance << endl;
cout << "Transactions: " << transactions << endl;
};
the global variables have already been initialized.
What I've tried:
I originally tried to cout << account.PrintStatement() << endl; however I get an error C2679 (binary '<<' : no operator found which takes a right-hand operand of type 'void' (or there is no acceptable conversion)
I thought maybe changing things to apply to a string function instead would work, but instead I get a bunch of int conversion errors etc.
I'm unsure of what to do.
I am required to put these in a function just to be clear.
I tried using this question https://stackoverflow.com/questions/12766858/how-to-call-void-function-from-main to help me, it made sense that the poster was using a reference, but I do not have that. Is there another way?
I originally tried to cout << account.PrintStatement() << endl;
Well, the expression account.PrintStatement() is abject nothingness because the function has a void return type. As you've indicated, the function returns nothing, so there is nothing to stream to cout.
The function itself has already streamed a bunch of stuff to cout, fulfilling all your couty needs. So, simply invoke it:
account.PrintStatement();
That's it!
Just call the method on your instance of the class. It doesn't need to return anything; it will do the counts you want and then return to main.
When we use cout<<something_here, the compiler will interpret it as "print the value of something_here". Now, something_here can be a lot of things. When it is a function, cout will print the value returned by the function. In your case, the return type is void i.e. nothing. So, there is nothing to print.
To fix your issue, you can directly call account.PrintStatement(); since you have already printed what you wanted to print inside this function.

C++ Array passed by reference, but how to understand this?

The arrays are passed by reference. Any changes made to the array within the function changeArray will be observed in the calling scope (main function here).
However the codes below print 0 1 in the 1st cout, and print 2 in the 2nd "cout". What I don't understand is that why the first cout prints the original value of array[0]=1 instead of the changed value of array[0]=2?
Thanks a lot.
#include <iostream>
using namespace std;
int changeArray(int array[]) {
array[0]=2*array[0];
return 0;
}
int main() {
int array[]={1,2,3,4};
cout << changeArray(array) << " " << array[0] << endl;
cout << array[0] << endl;
return 0;
}
To make sure that the compiler doesn't reorder the execution:
cout << array[0] << endl;
changeArray(array);
cout << array[0] << endl;
This prints 1 and then 2.
The C++ compiler is allowed to optimize the code by reordering the execution of code within a single expression (e.g. cout << changeArray(array) << " " << array[0] << endl). To avoid that, and to make sure changeArray gets called first, you need to split your expression to separate statements, e.g. by using the semicolon (;). Everything before the semicolon gets executed before anything after the semicolon can start.