newbie question here, can anybody provide an answer to why this loop is not terminating? I am refrencing the address of the variable, then de-referencing it and adding one to it. By my logic it should terminate by ~ the 10th step.
Thanks!
#include <iostream>
using namespace std;
int addtoi(int intern);
int main(){
for(int i = 0; i < 10;addtoi(i)){
}
}
int addtoi(int intern){
int *pt;
pt = &intern;
++*pt;
cout << *pt << "\t" << intern << "\n";
return 0;
}
Your loop is not terminating because any changes that you made to intern inside addtoi stay inside addtoi. The fact that you take a pointer there has no effect, because it's too late: you are taking a pointer of a local variable, which is a copy of i passed in.
You can fix this by passing in intern by reference, like this:
int addtoi(int& intern) {
intern++;
cout << intern << "\n";
return 0;
}
You do not need to take its address - simply modifying it will change the value of i inside the loop.
You don't change the value of i anywhere in your loop. You do pass its value to addtoi, but passing a value can't change the value of the variable whose value you took. So why would it ever end?
If you pass a reference or pointer to i to addtoi, then it can change i's value. But if you only pass the value itself, then it can only change the value passed to it, which has no effect on i's value.
What do you think would happen if you did this:
addtoi(1);
Do you think that constant 1 would somehow change? Same thing -- if you pass a value, you can't change anything in the caller since all you got was a value.
Consider:
int j = 1;
int i = 1;
addtoi(i);
addtoi(j);
addtoi(1);
These three calls all pass the same value to addtoi, 1. It makes no difference how you obtain that value if all you pass is the value.
The loop is not terminating because when you do addtoi(i), the value of i is send to the addtoi() function and not the original i variable. Its a classic example of pass by value.
Related
I've made this example to show what I'm talking about. I want to know if there is a way to run through main() without resetting value to 0.
int main(){
int value = 0;
value++;
cout << value << endl;
main();
}
Before answering the question, your example has two big problems
Calling, or even taking the address of, main is not allowed.
Your function has infinite recursion which makes your program have undefined behavior.
A different example where value is saved between calls could look like this. It uses a static variable, initialized to 0 the first time the function is called, and is never initialized again during the program execution.
#include <iostream>
int a_function() {
static int value = 0;
++value;
if(value < 100) a_function();
return value;
}
int main(){
std::cout << a_function(); // prints 100
}
If you want to keep the variable value local to the main function, you can declare it as static int value = 0;.
As has been pointed out in various comments though, recursively calling any function without an escape mechanism like you are is a bad idea. Doing it with main is a worse idea still apparently not even possible.
In the following call-by-value example, I cannot understand why this code is not changing the value of the 5 to a 6.
Line 11 calls the function changeValue which has the value 6, so I would have thought 6 should be output, however 5 is still output?
#include <iostream>
using namespace std;
void changeValue(int value);
int main()
{
int value = 5;
changeValue(value);
cout << "The value is : " << value << "." << endl;
return 0;
}
void changeValue(int value)
{
value = 6;
}
// This doesn't change the value from 5 to 6. 5 is output?
When you pass a function argument by value a copy of the object gets passed to the function and not the original object.Unless you specify explicitly arguments to functions are always passed by value in C/C++.
Your function:
void changeValue(int value)
receives the argument by value, in short a copy of value in main() is created and passed to the function, the function operates on that value and not the value in main().
If you want to modify the original then you need to use pass by reference.
void changeValue(int &value)
Now a reference(alias) to the original value is passed to the function and function operates on it, thus reflecting back the changes in main().
The value of value isn't changing because your int that you pass to the function is being copied into the stack frame of the function, then it's being changed, and when the function exits the copy is destroyed. The original in main's stackframe has not changed, since it was copied to the changeValue.
If you want to change it, you should pass a reference to an int, like so void changeValue(int& value), which says that the value isn't copied into the function, but merely an alias to the original is passed.
The behavior being observed currently is because passing by value means a copy of value (new integer with value of value) is actually passed to the function.
You have to pass by reference. For that the changeValue function will look like this:
void changeValue(int& value)
Rest of the code will remain the same.
Passing a variable by reference means the same int value declared in main is passed to the changeValue function.
Alternatively, you can pass a pointer to value to the changeValue function. That will however, require changes to how you call the function also.
int main()
{
int value = 5;
changeValue(&value);
...
return 0;
}
void changeValue(int* value)
{
*value = 6;
}
I'm including this answer as another way to think about writing functions and passing parameters by value.
You could also have written this code in the following way. That is pass the parameter by value, modify the local copy in the function, which does not alter the original value, and return the altered value.
int changeValue(int val)
{
val = 6;
return val;
}
int main()
{
int value = 5;
value = changeValue(value);
cout << "The value is : " << value << "." << endl;
return 0;
}
I am not in any way indicating my suggestion for your program is better than passing by reference. Instead, it is just the way learning a functional programming language (Clojure) is affecting the way I think.
Also, in languages like Python, you cannot modify a scalar parameter. You can only return a new value. So my answer is more of an exercise in thinking about things differently in C/C++.
AND:
the copy is assigned 6, but the change is not returned.
you need some reference or pointer if you want to change the value:
try using a method signature like:
void changeValue(int& value)
that will probably do what you expected
This is because the change in the changeValue () function is local. When you can changeValue (value) the contents of the variable value in main is copied in the formal argument named value (same name) of the function. Same name does not mean that the both are same. The value you are accessing inside the function is a copy of the value you had in the main.
To change you either need to pass it by reference or a pointer
void changeValue (int *val)
{
*val = 6;
}
call with changeValue (&value) in main
This works because the address of the variable value in main is passed and this address value is copied into val of the function. By doing *val we can get the contents of the address which was copied into val, which in actually the contents of value in main.
OR
void changeValue (int &val)
{
val = 6;
}
I'm playing around with pointers to understand this concept better
and wanted to ask
Why do i get null pointer as return for the second function?
and why it isn't possible to get the address 0x7fff15504044.
What is happening and where inside memory is the integer 5 stored,
when im working with it inside the function?.
#include <iostream>
using namespace std;
int* return_adress(int* input){ return input; }
int* return_adress_from_input(int input){ return &input; }
int main(){
int k = 3;
cout << return_adress(&k) << endl;
cout << return_adress_from_input(k) << endl;
}
Output:
0x7fff15504044
0
With int* return_adress_from_input(int input), input is a value copy of k in the caller. They are two different variables therefore with different addresses.
input goes out of scope conceptually once the closing brace of the function is reached.
The pointer &input then points to memory that you no longer own, and the behaviour of reading that pointer value (let alone dereferencing it) is undefined prior to C++14, and implementation defined from and including C++14.
Because you pass input by value, not by reference. Compiller first creates a local copy of input and then returns address of this local copy. To get the variable address use
int* return_adress_from_input(int& input){ return &input; }
In general, you get undefined behavior which can lead to returning nullptr in the particular case
On my PC i get
00AFFC80
00AFFBA8
so you are just lucky with zero return
As a beginner in C++, first thing I came accross for functions is that they use a copy of the argument, for example if we execute this :
void add (double x){
x=x+3;
}
int main(){
double x=2 ;
add(x) ;
}
Then x would actually be equal to 2, not 5. Later on, learning about pointers, I found the following :
void fill (int *t){
for (int j=0, j<10, j++){
t[j]=j;
}
int main(){
int* p;
p = new int[10];
fill(p);
}
Now if we print what p contains, we find that it's indeed filled by the integers. I have some trouble understanding why it does that as I feel like it should have been the same as the first function ?
Thanks.
The reason it isn't the same as the first function is because you are passing the pointer by value. This means that if you modify the actual pointer, e.g by assigning to it, then it would only be in that state inside the function. The value that the pointer points to is still the original value, which will get modified since both copied pointers point to that same original value (don't forget notation of the form a[i] is equivalent to *(a + i), which does a dereference and is modifying the pointed value, not the pointer itself).
A small example that illustrates this would be the following (not accounting for memory leaks):
#include <iostream>
int test(int* x)
{
int* y = new int{10};
x = y;
std::cout << "Inside function: " << *x << "\n";
}
int main()
{
int* t = new int{5};
std::cout << "Before function: " << *t << "\n";
test(t);
std::cout << "After function: " << *t << "\n";
}
In first example you are using ordinary variable. When passing normal variable to function, like this, the function creates its own copy of the variable (it has same value as it has when you passed it, but it was copied to different place in memory). That is standard behaviour.
In second example you are using pointer: we can say that it points to the place in memory, where values are stored. Few of the advantages of them:
1) If you want to spare memory, but need to use same value in different functions -> mostly appplies to bigger objects than double, like array in your example
2) If you need to change value of variable/array/object in different functions
But careful, in the second function you still created copy, but not of value, but pointer. So basically, the "new" pointer is different object, but it is pointing to the same place in memory, so when accessing the value (which you are doing with [j]), you are editing the same place in memory.
It is not that easy concept to grasp, especially with more dimentional arrays, but hope this helped a little. You can learn some more in tutorials or c++ docs, for example this is a good one: https://www.geeksforgeeks.org/pointers-in-c-and-c-set-1-introduction-arithmetic-and-array/
In the following call-by-value example, I cannot understand why this code is not changing the value of the 5 to a 6.
Line 11 calls the function changeValue which has the value 6, so I would have thought 6 should be output, however 5 is still output?
#include <iostream>
using namespace std;
void changeValue(int value);
int main()
{
int value = 5;
changeValue(value);
cout << "The value is : " << value << "." << endl;
return 0;
}
void changeValue(int value)
{
value = 6;
}
// This doesn't change the value from 5 to 6. 5 is output?
When you pass a function argument by value a copy of the object gets passed to the function and not the original object.Unless you specify explicitly arguments to functions are always passed by value in C/C++.
Your function:
void changeValue(int value)
receives the argument by value, in short a copy of value in main() is created and passed to the function, the function operates on that value and not the value in main().
If you want to modify the original then you need to use pass by reference.
void changeValue(int &value)
Now a reference(alias) to the original value is passed to the function and function operates on it, thus reflecting back the changes in main().
The value of value isn't changing because your int that you pass to the function is being copied into the stack frame of the function, then it's being changed, and when the function exits the copy is destroyed. The original in main's stackframe has not changed, since it was copied to the changeValue.
If you want to change it, you should pass a reference to an int, like so void changeValue(int& value), which says that the value isn't copied into the function, but merely an alias to the original is passed.
The behavior being observed currently is because passing by value means a copy of value (new integer with value of value) is actually passed to the function.
You have to pass by reference. For that the changeValue function will look like this:
void changeValue(int& value)
Rest of the code will remain the same.
Passing a variable by reference means the same int value declared in main is passed to the changeValue function.
Alternatively, you can pass a pointer to value to the changeValue function. That will however, require changes to how you call the function also.
int main()
{
int value = 5;
changeValue(&value);
...
return 0;
}
void changeValue(int* value)
{
*value = 6;
}
I'm including this answer as another way to think about writing functions and passing parameters by value.
You could also have written this code in the following way. That is pass the parameter by value, modify the local copy in the function, which does not alter the original value, and return the altered value.
int changeValue(int val)
{
val = 6;
return val;
}
int main()
{
int value = 5;
value = changeValue(value);
cout << "The value is : " << value << "." << endl;
return 0;
}
I am not in any way indicating my suggestion for your program is better than passing by reference. Instead, it is just the way learning a functional programming language (Clojure) is affecting the way I think.
Also, in languages like Python, you cannot modify a scalar parameter. You can only return a new value. So my answer is more of an exercise in thinking about things differently in C/C++.
AND:
the copy is assigned 6, but the change is not returned.
you need some reference or pointer if you want to change the value:
try using a method signature like:
void changeValue(int& value)
that will probably do what you expected
This is because the change in the changeValue () function is local. When you can changeValue (value) the contents of the variable value in main is copied in the formal argument named value (same name) of the function. Same name does not mean that the both are same. The value you are accessing inside the function is a copy of the value you had in the main.
To change you either need to pass it by reference or a pointer
void changeValue (int *val)
{
*val = 6;
}
call with changeValue (&value) in main
This works because the address of the variable value in main is passed and this address value is copied into val of the function. By doing *val we can get the contents of the address which was copied into val, which in actually the contents of value in main.
OR
void changeValue (int &val)
{
val = 6;
}