Call-by-reference and Call-by-value - c++

I am writing a program that lets the user input an integer into the variable value, and calls the two alternate functions, each of which triples the chosen integer value.
The function triple_by_value passes the variable number by value, triples the parameter and returns the result.
The function triple_by_reference passes the variable number by reference, and triples the original value of number through the reference parameter.
#include <iostream>
using namespace std;
int main()
{
cout << "Enter a number (-1 to end): ";
cin >> value;
if (value != -1)
{
triple_by_value(value);
cout << "Triple-By-Value: " << value << endl;
triple_by_reference(value);
cout << "Triple-By-Reference: " << value << endl;
}
return 0;
}
int triple_by_value(int value)
{
value *= 3;
return value;
}
int triple_by_reference(int &value)
{
value *= 3;
return value;
}
It seems I'm having a problem where the function triple_by_value isn't, well, tripling the value, just printing it as is.
Any help would be much appreciated.

As the name suggests, passing a variable by value means that the function only gets the value of the variable and not access to the variable itself.
In your example, int value is a whole different variable from value in main, just that it has the same value. However, int &value is a reference to value in main, which means it is safe to think of it as the value in main itself.
If you print value in triple_by_value after value *= 3 you will get the value that you want. If you want value in main to have the new value, you can assign the new value to value in main by doing value = triple_by_value(value); in main, or simply use triple_by_reference.

Related

Return value unchanged by function

After calling function the amount_of_people, the variable n remains unchanged. I verified this by outputting the variable after the function call. Do I need a pointer n to function as argument?
int main(){
srand(time(NULL));
bool Appworks = true;
size_t n;
do {
amount_of_people(n); // Entering amount of people HERE! STUCKED HERE.
if (n >= 1) {
DataBase *first = new DataBase[n]; // Creating dynamic structure-array
inputData(first, n);
output(first, n); // Output of entered data
freeUp_memory(first); // Clearing dynamic-alocated memory engaged by early-created pointer
}
else cout << "Error! Wrong amount of people!" << endl;
} while (Appworks);
system("PAUSE");
return 0;
}
Function declaring:
unsigned amount_of_people(int n) {
cout << "Enter how many people u want to enter" << endl;
cin >> n;
return n;
}
I would appreciate any help and explanation(!)
Thanks for your attention.
amount_of_people(n)
does not use the value returned from amount_of_people. n is of no use here because according to the function declaration
unsigned amount_of_people(int n);
n is passed by value. When a parameter is passed by value, the function operates on a copy of the source variable. Changing the copy has no effect on the original. May I suggest instead,
std::size_t amount_of_people() // parameter gone, return type changed to match n in caller
{
std::size_t n; // parameter moved to here and type changed to match return type
std::cout << "Enter how many people u want to enter" << std::endl;
std::cin >> n;
return n;
}
This is then used like
const std::size_t n = amount_of_people();
Side note: Rather than
DataBase *first = new DataBase[n];
strongly consider ensuring that DataBase correctly observes the Rule of Three, Five, or Zero and using
std::vector<DataBase> databases;
rather than a raw allocation. It knows it's size and looks after all of the memory management for you. Documentation for std::vector.
RE "Do I need a pointer to function as argument", either a pointer or a reference.
unsigned amount_of_people(int n) as you wrote it takes an integer n by value, assigns it using cin >> n, and then returns it. Either change your function to
void amount_of_people(unsigned int& n) {
std::cout << "Enter how many people u want to enter" << endl;
std::cin >> n;
}
and call it:
amount_of_people(n);
which takes n by reference, or write
unsigned int amount_of_people() {
unsigned int n;
std::cout << "Enter how many people u want to enter" << endl;
std::cin >> n;
return n;
}
and call it:
n = amount_of_people();
Both styles have uses; the first is, I think, more common in cases where the function has side effects, and so it "outputs" its results into the ref-passed parameters ("out parameters"), while you opt to return from the function a variable indicating whether an error occurred during its execution. The second style is a little more common for pure functions, where the result is always computed successfully based on the inputs with no possibility of error.
Also, make up your mind whether you want the variable to be a size_t or an int.

Passing and updating a structural array

So I'm having some trouble with my program. It doesn't seem to fill the array properly. It dosen't seem to populate pass element 0, even though I'm increasing i. When I debug and go back, i remains zero. Should I be doing something different? I feel like I'm passing or updating the array improperly. Can't really use any STL libraries. Thank you in advance for any help.
struct Client
{
string name;
string zip;
double balance;
};
Client bAccounts [30]; //structural array in main()
int addClnt(Client(&bAccounts)[30], int); //prototype
int addClnt(Client(&bAccounts)[30], int clientCount) //function to add
elements
{
cout << "Enter Account Name:" << endl;
cin >> bAccounts[i].name;
cout << "Enter Account Zip:" << endl;
cin >> bAccounts[i].zip;
cout << "Enter Account Balance:" << endl;
cin >> bAccounts[i].balance;
cout << "Enter Last Transaction" << endl;
cin >> bAccounts[i].lastTrans;
clientCount++; //to return number of clients added
i++; //to populate different element of array on next call of function.
return clientCount + 1;
}
So I added + 1 to return clientCount and then set i = clientCount. However, clientCount remains at zero and dosen't update.
The reason the array doesn't have any values after the first one is because you never reach passed the first element. You increment i at the end of the function, but at the top of your addClnt function, i is set back to 0 . This will just keep resulting on overwriting the old previous data
EDIT:
#include <iostream>
//use pass by reference (&)
void add_client(int& index_loc){
//do whatever
//this changes the actual value passed into the function
index_loc++;
}
int main(){
int loc = 0;
add_client(loc);
add_client(loc);
add_client(loc);
//outputs 3
std::cout << "current #: " << loc << "\n";
}
clientCount is only getting incremented in that functions scope. When that function goes to it's return statement, all variables and all the work it did has completely died.
You are passing clientCount by value and not by reference, so clientCount will always be 0, and incrementing it inside that local function won't actually change clientCount's value outside of the function.
What you need to do is pass it by reference.
EDIT: The chosen answer does not explain why his solution works. The answer provided is incorrect.
The reason why the code works because again, you pass by reference and not by value.

My bool function keeps returning true and im not sure why

Im doing an excercise sheet to get an understanding of functions and I am currently working on the following question.
Write function prototypes for each of the following:
A function HasValue that may be passed a reference to an array, the size of the array and a
search value. The function should return true if the search value exists in the array
In my code I have sent the contents of the array, the array size and the value to be searched in the array to the bool function.
In the function I compared the value to each element of the array using a for loop.
I then created a variable count in the function that will be incremented if the value matches any element in the array.
I then used an if else statment to return true if count is greater than 0 and false if count is equal to 0. The problem is however that the function is only returning true thus the output will always be "this number appears in the array"
Logically these steps seem correct to me but obviously there is a flaw somewhere that I cant see. I presume its just I do not have a decent understanding of Bool functions yet but if someone could explain where and why I'm going wrong it would be greatly appreciated in my learning process to understanding functions and c++.
#include <iostream>
#include <iomanip>
#include "stdafx.h"
using namespace std;
bool HasValue(int Array[], int size, int Value);
int main()
{
int value;
int Array[10]{ 3,5,6,8,9,1,2,14,12,43 };
cout << "enter value you wish to search for in array " << endl;
cin >> value;
HasValue(Array, 10 , value);
if (true)
cout << "This number appears in the array " << endl;
else
cout << "This number does not appear in the array " << endl;
return 0;
}
bool HasValue(int Array[], int size, int Value)
{
int count = 0;
for (int i = 0; i < size; i++)
{
if (Value == Array[i])
{
count++;
}
}
if (count > 0)
{
return true;
}
else
return false;
}
You test code is the problem
HasValue(Array, 10 , value);
if (true)
cout << "This number appears in the array " << endl;
else
cout << "This number does not appear in the array " << endl;
This ignores the return value of HasValue and always prints "This number appears in the array".
HasValue(Array, 10 , value);
This line of code executes the function but ignores the returned value. When a function returns a value, you need to assign it to a variable:
bool result = HasValue(Array, 10 , value);
Then if (true) does not have any reference to the returned value. The true inside the if will cause the first cout to always print. You will never see the output from the else. But once you have the return value in a variable, you can use it in the if:
if(result)
You can reduce this all to one line of code, if you want:
if(HasValue(Array, 10 , value))
Now the if statement will directly test the return value from HasValue(). In this particular case, combining the code into a single line seems reasonable. You must be careful doing this, though. When you combine too much into a single line, the code becomes more difficult to debug. You will need to find a balance between readability and convenience as you continue learning how to program.

Function call passing incorrect number (C++ 11)

I'm currently working on a project that is meant to teach the usage of functions in C++. I've worked with python in the path and have a reasonable understanding of functions in code (or so I thought) but for some reason I'm getting some alarming errors when I pass values through to my current function.
This is the entire code, my problem lies within the narc_num(153,3) call made in main. I added some cout statements into the narc_num function to see why I was getting wonky results and found that the num argument was getting passed as a completely different number. Why would this be?
#include<iostream>
#include<cmath>
using std::cin;
using std::cout;
using std::endl;
/*
Function: order_parameters
Purpose: If first is greater than second reassign the values so second is greater than first
Algorithm:
1.Pass arguments as references to first and second
2.if statement that runs if first is greater than second
3.within if statement switch values using a temporrary variable
4.if else doesnt run nothing happens
*/
void order_parameters(long & first,long & second)//passing long references of first and second
{
if(first > second)//start if when the ref to first > ref to second
{
long temp; // initialize temp
temp = second; //value temp is = to second
second = first; //second will now be first, temp is still = to first though as well
first = temp; //second is now set = to temp, which is first. dat swap
}//end if
}
/*
Function: narc_num
Purpose: check if a number is indeed a narcisstic number
Algorithm:
1.Pass num, the number to be checked, and power, the order the number will be checked against
2.use a while loop to iterate through digits of number
-mod10 takes the last digit, the digit is raised to the power passed as an argument
-the value found is added to the total
-the number is then divided by 10 to remove the last digit, reiterates again.
3.the total found by the while loop is checked against the number passed an as argument
-if the total is equal to the number it is narcisstic.
*/
bool narc_num(long num, long power)// will return a boolean value, passing num and power integers
{
//split all digits into seperate numbers, add together raised to power
long total = 0,digit,num_copy;
bool narc = false; //value to check if number is narcissitic or not
num = num_copy;
cout << "number"<< num << endl;
while(num > 0)
{digit = num%10;
cout <<"digit" << digit << endl;
total += pow(digit,power);
cout <<"total" << total << endl;
num /= 10; //divides by 10 to go to the next digit down
}
if (total == num)
narc = true;
cout << total << endl;
return narc;
}
long check_range(long first,long last,long power)
{
bool check;
order_parameters(first,last); //make sure parameters are in correct order
for(first;first == last;first++);//iterate through all numbers from first to last
{check = narc_num(first,power); //check = True if narc number otherwise false
if (check == true)
{cout << first <<" is a narcissistic number of order " <<power<< endl;
};
cout << "gothere"<< endl;
};
cout << "dick canoe"<< endl;
}
int main(){
narc_num(153,3);
}
You are assigning the value of num_copy (an uninitialized long) to num near the top of the narc_num function. I believe you meant to assign num_copy the value of num. This is probably the cause of your unexpected results.

Passing an array by reference using pointers in C++

In some new territory working with pointers and references, I am attempting to pass an array by reference into a function using a pointer, however I keep getting errors no matter what I try, I am sure the problem is very simple to fix but I just cant seem to wrap my head around it, can anyone see the mistake im making? any help will go a long way thanks
#include<iostream>
#include<cmath>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <new>
using namespace std;
//Inline function
inline double getFahrenheit(double theCelsius)
{
//Convert the celcius to farenheit
return (theCelsius + 32) * 5 / 9;
}
void outputWeather(double *temperaturesArray, const string WEEK_DAY_NAMES[], const double MAX_NUMBER)
{
//this is a counter that will increment through the days and various
int counter;
//reset the counter to 0 so we can use it again
counter = 0;
//print a header
cout << "THIS WEEKS TEMPERATURE REPORT " << endl;
//print a divider
cout << "=============================" << endl;
//while the counter is less than 7 repeat again
while(counter < MAX_NUMBER)
{
//print out the temperatures by day
cout << WEEK_DAY_NAMES[counter] << " " << temperaturesArray[counter] << "\370C " << getFahrenheit(temperaturesArray[counter]) <<"\370F "<< endl;
//increase the counter by 1
counter +=1;
}
}
//Function that will determine whether or not the value the user entered was numeric and within the range
double checkValidation(string weekDay)
{
//Create a variable to store a valid number
double validNumber;
//This will hold the value for the lowest
const double MIN_NUMBER = 1;
//This will hold the value for the highest temperature
const double MAX_NUMBER = 365;
//This will hold the value for the valid number that the user will eventually enter
validNumber = 0.0;
//This will alert the user to enter a temperature for that day of the week
cout << "Please enter the temperature for " << weekDay << endl;
//This will take in teh value the user entered for teh temperature
cin >> validNumber;
//If the text the user entered was not numeric start again
if(cin.fail())
{
//C++ built in methods for clearing the cin
cin.clear();
fflush(stdin);
//alert the user what they typed was wrong
cout << "invalid input. please try again and enter a numeric value" << endl;
//pass in the weekeday and start over
checkValidation(weekDay);
}
else
{
//if teh number falls outside the range
if(validNumber < MIN_NUMBER || validNumber > MAX_NUMBER)
{
//Alert the user that it was outside the range
cout << "invalid input. please try again and enter a value between -90 and 60" << endl;
//pass in the weekday and try again
checkValidation(weekDay);
}
}
//return the valid number
return validNumber;
}
int main()
{
//this is a counter that will increment through the days and various
int counter;
//a constant to hold the variable for the number of days
const int MAX_COUNTER = 7;
//an array that will hold all the days of the week
const string WEEK_DAY_NAMES[] =
{
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
};
//this will hold all of teh temperatures
double temperaturesArray[MAX_COUNTER];
//start the counter off at 0
counter = 0;
//begin telling the user to enter temperatures by printing a header
cout << "Please enter the temperature for every day of the week " << endl;
//while the counter is less than 7 we will repeat
while(counter < MAX_COUNTER)
{
//add temperature to the array
temperaturesArray[counter] = checkValidation(WEEK_DAY_NAMES[counter]);
//add 1 to the counter
counter +=1;
}
double * arrayPointer = new double[MAX_COUNTER];
arrayPointer = &temperaturesArray;
outputWeather(arrayPointer, WEEK_DAY_NAMES, MAX_COUNTER);
system("PAUSE");
return 0;
}
In C++, the size of an array is encoded into its type.
There is no general "array of doubles" type. But there is an "array of 7 doubles" type, and an "array of 13 doubles" type, and so on.
So to pass an array as an array, and not simply as a pointer, to a function, you need to encode the precise type in the function's signature.
It won't be "a function which takes an array", but "a function which takes an array of size 7".
The way to do that is as follows:
void f(double (&arr)[7]);
Or of course, you can template it, if the array size is not fixed:
template <size_t N>
void f(double (&arr)[N]);
But really, what you're trying to do shouldn't be done using raw arrays at all.
Use the standard library vector.
Briefly, replacing line
arrayPointer = &temperaturesArray;
with
arrayPointer = temperaturesArray;
makes the code to compile.
Notice that arrayPointer is of type double* and temperaturesArray is of type double[MAX_COUNTER] (with MAX_COUNTER = 7). Hence, you can assign arrayPointer to the address of a double but you cannot assign arrayPointer to the address of a double[MAX_COUNTER]. That's what the original code attempted to do and thus, it failed to compile.
On the other hand, each element of a double[MAX_COUNTER] is a double. In particular, the first element is a double and you can assign its address to arrayPointer:
arrayPointer = &temperaturesArray[0];
The fix above is just a synctatic sugar for this line. Indeed, when you assign an object of type "array of type T" (e.g. double[MAX_COUNTER]) to a "pointer of type T", then the compiler performs the so called array-to-pointer conversion which means that is assigns the address of the first array element to the pointer.
Now a little remark on your code (with the provided fix), specifically, the following lines:
double * arrayPointer = new double[MAX_COUNTER];
arrayPointer = temperaturesArray;
The first line above allocates heap memory to store an array of MAX_COUNTER objects of type double. Then the address of the first element of this array is assigned to arrayPointer.
Then, the following line reassigns arrayPointer to the address of the first element of temperaturesArray. Therefore, the address of the first element of the heap allocated array is lost and you can no longer delete it. Remeber that every call to new must be matched by a call to delete (otherwise you have a memory leak). In this particular case, however, the best thing to do isn't call delete. Actually, you should eliminate the call to new since the heap memory is never used. More precisely, you can remove the first line above.