Return value unchanged by function - c++

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.

Related

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.

Call-by-reference and Call-by-value

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.

C++ Returning a value of an array from function won't work and resets to 0 every time its ran [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am trying to find greatest number entered, and then display it to the user.
So once the user enters several numbers, program calls function that will find it and then return it. Unfortunately every time I run it, the number resets to zero even after the function has worked successfully. What do I do wrong?
Visual Studio mentions this: Run-Time Check Failure #3 - The variable 'gromax' is being used without being initialized.
int largestGroup(int groupsize[], int theValue)
{
int gromax=groupsize[0];
for (int i=1;i<9;i++){
if(groupsize[i] > gromax){
gromax=groupsize[i];
}
}
return gromax;
}
int main()
{
int groupsize[10]={0,0,0,0,0,0,0,0,0,0};
int gromax = groupsize[0];
char newentry='n';
do{
cin >> groupsize[i];
cout << string(60, '\n');
cout << "Would you like to enter another questionare? Enter either 'y' or 'n': " << endl;
cin >> newentry;
cin.ignore();
}while((newentry =='y') || (newentry=='Y'));
largestGroup(groupsize, i);
cout << "Number of customers in largest group today was " << gromax << endl;
Insert in the very beginning of main
int i = 0;
and inside the loop increase it as for example
cin >> groupsize[i++];
Change this
largestGroup(groupsize, i);
statement to
int gromax = largestGroup(groupsize, i);
And remove statement
int gromax = groupsize[0];
Also you shall check in the loop that you are not trying to acces a memory beyond the array.
And function largestGroup is wrong.
int largestGroup(int groupsize[], int theValue)
{
int gromax=groupsize[0];
This declares a function that - despite appearances - actually takes an array and an integer (inherited from C, arrays can decay to pointers as necessary, and it's deemed necessary when someone tries to pass them to functions).
Then, it declares a private local variable, gromax. This value, think of it as largestGroup::gromax, exists only for the life time of each individual call to the function. The last line of the function is then paramount.
return gromax;
}
This pushes the "gromax" into whatever CPU register/location return values are stored. It will live there until something else uses the value.
The language does not automatically transfer the value anywhere, even if your calling function has a variable of the same name.
So, the bug in your code is this:
largestGroup(groupsize, i);
You call the function, and you never capture the return value.
gromax = largestGroup(groupsize, i);
would capture the value.
Be aware that arrays are passed by address/pointer (live demo: http://ideone.com/DTkbFn)
#include <iostream>
void f(int groups[5], int x)
{
x = 3;
groups[x] = 999;
}
int main()
{
int groups[5] = { 0, 1, 2, 3, 4 };
int x = 10;
std::cout << "before: x = " << x << ", groups[3] = " << groups[x] << '\n';
f(groups, x);
std::cout << "after: x = " << x << ", groups[3] = " << groups[x] << '\n';
return 0;
}
When you pass an array, you are actually passing by pointer, so normal "pass by value" behavior does not apply.
int largestGroup(int groupsize[], int thevalue)
is actually equivalent to
int largestGroup(int* groupsize, int theValue)
It is advisable to use the second syntax to avoid falling into the trap of thinking you can modify groupsize with no impact on the caller.
You didn't use the return value. Try:
gromax = largestGroup(groupsize, 1);

Deleting duplicates in an array (C++)

I saw an older post on here asking how to do relatively the same thing, but their approach was different and i'm interested to know the hole in my program.
I am attempting to write a program that accepts characters into a 10 character length array. I want the program to evaluate the first array position and delete any duplicates it finds later in the array by identifying a duplicate and moving all of the values to the right of it to the left by one. The 'size' of the array is then decreased by one.
I believe the logic I used for the delete function is correct but the program only prints an 'a' for the first value and the fourth value in the array.
Any help would be greatly appreciated, here is my code:
#include <iostream>
using namespace std;
int letter_entry_print(int size, char array[10]);
int delete_repeats(int& size, char array[10]);
int final_array_print(int size, char array[10]);
int main()
{
char array[10];
int size = 10;
letter_entry_print(size,array);
delete_repeats(size,array);
final_array_print(size,array);
cout<<"\n";
system("pause");
}
int letter_entry_print(int size, char array[10])
{
int i;
for (i=0;i<size;i++)
{
cout << "Enter letter #" << i+1 << endl;
cin >> array[i];
cout << "\n";
}
cout << "\nYour array index is as follows:\n\n";
for (i=0;i<size;i++)
{
cout << array[i];
cout << " ";
}
cout <<"\n\n";
return 0;
}
int delete_repeats(int& size, char array[10])
{
int ans;
int loc;
int search;
int replace;
char target='a';
cout << "Enter 1 to delete repeats.\n\n";
cin >> ans;
if(ans==1)
{
for(loc=0;loc<size;loc++)
{
array[loc]=target;
for(search=1;search<(size-loc);search++)
{
if(target=array[loc+search])
{
for(replace=0;replace<(size-(loc+search));replace++)
{
array[loc+search+replace]=array[loc+search+replace+1];
array[size-1]=0;
size=(size-1);
}
}
}
}
}else(cout<<"\nWhy didn't you press 1?\n\n");
return 0;
}
int final_array_print(int size, char array[10])
{
cout<<"\nYour new index is as follows:\n\n";
int i;
for(i=0;i<size;i++)
{
cout<<array[i];
cout<<" ";
}
cout<<"\n";
return 0;
}
Ok, there are a few things about your code that look odd.
1) you repeat 10 all over the place to the point where there's no way you could resonably change it, but you also pass size along. Instead of making all your functions take arrays of 10 chars, consider just passing in a pointer to char, like:
int final_array_print(int size, char *array)
then you can change the size of your arrays more easily. There's no point in passing size everywhere if you're going to limit yourself forever to 10 items, and there's no good reason to pass arrays of 10 items around if you provide a size!
2) ok, so now you want to look for duplicates. Why do you overwrite the first element in your array with an 'a'?
char target='a';
...
array[loc]=target;
wouldn't you want to do it the other way around?
3) next, as #Mahesh points out, you probably want to use the comparison operator '==' rather than the assignment operator = when looking for duplicates that is:
if(target=array[loc+search])
should probably be
if(target == array[loc+search])
4) Next, dontbeafraidtousealittlewhitespacebetweenyourwordsandpunctuation.Itmakesitaloteasiertoidentifytypingmistakesandspellingerrors.
5) your loop to actually perform the replacement has incredibly complicated indices. It would be easier if you didn't start with replace = 0, but just start at replace = search + 1, try it out and perhaps you'll how much simpler all the rest of the indices become.