Global and local variables in C++ - c++

I'm fairly new to C++, and I'm experiencing some issues when printing local and global variables. Consider this simple piece of code:
#include <cstdlib>
#include <iostream>
using namespace std;
/*
*
*/
int x = 10; // This x is global
int main() {
int n;
{ // The pair of braces introduces a scope
int m = 10; // The variable m is only accessible within the scope
cout << m << "\n";
int x = 25; // This local variable x hides the global x
int y = ::x; // y = 10, ::x refers to the global variable x
cout << "Global: " << y << "\n" << "Local: " << x << "\n";
{
int z = x; // z = 25; x is taken from the previous scope
int x = 28; // it hides local variable x = 25 above
int t = ::x; // t = 10, ::x refers to the global variable x
cout << "(in scope, before assignment) t = " << t << "\n";
t = x; // t = 38, treated as a local variableout was not declared in this scope
cout << "This is another hidden scope! \n";
cout << "z = " << z << "\n";
cout << "x = " << x << "\n";
cout << "(in scope, after re assignment) t = " << t << "\n";
}
int z = x; // z = 25, has the same scope as y
cout << "Same scope of y. Look at code! z = " << z;
}
//i = m; // Gives an error, since m is only accessible WITHIN the scope
int m = 20; // This is OK, since it defines a NEW VARIABLE m
cout << m;
return 0;
}
My goal is practicing the accessibility of the variables within the various scopes, and then printing them. However, I'm not able to figure out why when I try to print the last variable z, NetBeans gives me back the output 2025.
Here it follows my sample output:
10
Global: 10
Local: 25
(in scope, before assignment) t = 10
This is another hidden scope!
z = 25
x = 28
(in scope, after re assignment) t = 28
Same scope of y. Look at code! z = 2520
RUN FINISHED; exit value 0; real time: 0ms; user: 0ms; system: 0ms
Hope that somebody can help me understanding what is going on! :)

is not that z is holding the value 2520 is the fact that you ommit to add a new line operator between printing z and printing m...
you are doing:
cout << "Same scope of y. Look at code! z = " << z;
}
int m = 20;
cout << m;
but you should do:
std::cout << "Same scope of y. Look at code! z = " << z << std::endl;
}
int m = 20;
std::cout << m << std::endl;
if you just followed the same criteria of labeling the output and doing something like
std::cout << "M is: "<<m << std::endl;
you would spotted the issue faster by observing the output:
25M is: 20

Related

C++ How works set of function's argument value?

I am learning C++ and I have code:
float x, y;
namespace X {
void SetMyX(float p) {
x = p;
}
void SetMyY(float p) {
y = p;
}
namespace XY {
void Set(float p = 0.0f) {
x = p;
p = y;
}
}
}
int main() {
X::SetMyX(5.4f);
std::cout << "x = " << x << " y = " << y << std::endl;
X::SetMyY(4.1f);
std::cout << "x = " << x << " y = " << y << std::endl;
X::XY::Set();
std::cout << "x = " << x << " y = " << y << std::endl;
return 0;
}
And output is:
x = 5.4 y = 0
x = 5.4 y = 4.1
x = 0 y = 4.1
And I figure out variable p sets value of x and then y sets value of p? But, how it is possible? In C++ you can also set value of function's argument or what?
It's just weird for me because I thought you can't just "editing" entered value and you must add another variable like result or something like that, or just return sum of two arguments, but change them?
Yes, the argument p is a completely normal variable and you can do everything with it.
This will also work in many other languages like C, Java, Javascript or Python.

question on c++ object construction and scope

this is a little bit difficult to put into words, here is the snippet,
int main() {
int i = 5;
{
int i(i);
i = i+5;
// int i = i;
// i = i + 5;
cout << "inner scope" << endl;
cout << i << endl;
}
cout << "outer scope" << endl;
cout << i << endl;
}
this give the correct output
inner scope
10
outer scope
5
But if I do this,
int main() {
int i = 5;
{
//int i(i);
//i = i+5;
int i = i;
i = i + 5;
cout << "inner scope" << endl;
cout << i << endl;
}
cout << "outer scope" << endl;
cout << i << endl;
}
This throws an runtime exception, and gives wrong output,
inner scope
-858993455
outer scope
5
I feel this seems to be jsomething to do with the difference in the sequence of calling of copy constructor and assignment constructor, but I am not entirely sure, please enlighten me.
When you shadow a variable you remove all trace of it within that scope, so:
int i = i;
This declares i to equal its (uninitialized) self. This variable is completely independent from the parent scope's i. This is effectively undefined behaviour.
Curiously the int i(i) approach uses the parent scope's i to initialize, though that's rather peculiar that it works out. It might not be defined behaviour though.
You should be using a different variable name if you need to relate these two somehow. You can shadow if there's no inter-dependency.
In other words:
int j = i;

Changing pointers in functions [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 4 years ago.
I am new to c++ coding and this question may seem childish to you all. But I am really not able to come up on a solution to my problem. Please help.
#include <iostream>
using namespace std;
int* getnew(int* x){
int temp = *x;
int* y = &temp;
cout << "from function address of y = " << y
<< " and value of y = " << *y << endl;
return y;
}
int main(){
int x = 100;
int* y = getnew(&x);
cout << "address of y = " << y;
cout << " and value of y = " << *y << endl;
return 0;
}
Output of this code :
from function address of y = 0x7ffee52aa914 and value of y = 100
address of y = 0x7ffee52aa914 and value of y = 1
What I thought should be the output :
from function address of y = 0x7ffee52aa914 and value of y = 100
address of y = 0x7ffee52aa914 and value of y = 100
Can someone explain where am I going wrong ?
Since you’re getting the address of temp, wich was declared inside a function, it’s scope belongs only to the function.
So, when you leave get_new() the temp var no longe exists ( get deallocated ). Then when you acess the same address ( the temp address) in main you access a space of memory that isn’t reserved, wich means that that space can be freely used by other vars and stuff of the program.
Try to use malloc to allocate a new space of memory and guarantee that the var still lives after the get_new returns (finishes). Here’s a example:
#include <iostream>
using namespace std;
int* getnew(int* x){
int temp = *x;
// return a memory address pointing to a ‘ sizeof(int )’ bytes reserved space.
int *y = malloc( sizeof(int) );
cout << "from function address of y = " << y << " and value of y = " << *y << endl;
return y;
}
int main(){
int x = 100;
int* y = getnew(&x);
cout << "address of y = " << y;
cout << " and value of y = " << *y << endl;
return 0;
}
EDIT:
Also do not forget to deallocate the memory when you're finished using it ( no longer needs it):
#include <iostream>
using namespace std;
int* getnew(int* x){
int temp = *x;
// return a memory address pointing to a ‘ sizeof(int )’ bytes reserved space.
int *y = malloc( sizeof(int) );
cout << "from function address of y = " << y << " and value of y = " << *y << endl;
return y;
}
int main(){
int x = 100;
int* y = getnew(&x);
cout << "address of y = " << y;
cout << " and value of y = " << *y << endl;
/*********** same code until here********/
//use free for each memory allocated by malloc()
free(y); //deallocates the memory pointed by *y*
free(other_y_if_it_exists);
return 0;
}

c++ lambda capture by value

I am reading through the C++ lambda section in chapter 3 of this book and the following code confuses me:
int x = 0;
int y = 42;
auto qqq = [x, &y] {
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
++y;
};
x = y = 77;
qqq();
qqq();
std::cout << "final y: " << y << std::endl;
This code prints out:
x: 0
y: 77
x: 0
y: 78
final y: 79
Why does qqq() not register that x has changed to 77? It was stated that passing by value means we can read but not modify data readable where the lambda was defined. Does that mean we can't see changes after it's definition?
That's because the variable is captured by value (i.e. copied) only once, when you define the lambda. It's not "updated" as you may believe. The code is roughly equivalent to:
#include <iostream>
int x = 0;
struct Lambda
{
int _internal_x; // this is used to "capture" x ONLY ONCE
Lambda(): _internal_x(x) {} // we "capture" it at construction, no updates after
void operator()() const
{
std::cout << _internal_x << std::endl;
}
} qqq;
int main()
{
qqq();
x = 77; // this has no effect on the internal state of the lambda
qqq();
}
Live on Coliru
By binding a variable by value to a lambda closure, you're effectively copying the value of the variable into a separate variable that is found inside the lambda object. Likewise, by binding a variable by reference, you're making such an internal variable to be a reference to the original variable instead, thus being able to "see changes" on the original variable.
Look at it like this. The following code...
#include <iostream>
int main()
{
int x = 0;
int y = 42;
auto qqq = [x, &y] {
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
++y;
};
x = y = 77;
qqq();
qqq();
std::cout << "final y: " << y << std::endl;
}
Is (kind of, but not exactly) syntactic sugar for...
#include <iostream>
class MyLambda
{
private:
int x;
int& y;
public:
MyLambda(int x, int& y) : x(x), y(y) {}
void operator()()
{
std::cout << "x: " << x << std::endl;
std::cout << "y: " << y << std::endl;
++y;
}
};
int main()
{
int x = 0;
int y = 42;
MyLambda qqq = MyLambda(x, y);
x = y = 77;
qqq();
qqq();
std::cout << "final y: " << y << std::endl;
}
With the exception of the special lambda syntax and the fact that you can't reference the lambda's type directly. By comparing the former with the later code, you should be able to clear out your understanding of closures.
The lambda uses the value at the time the lambda is defined (it makes a copy), not at the time it is invoked.
This might help: How are Lambda Closures Implemented?

Why does changing what a reference points to not throw an error?

Iv got to the stage in my c++ study concerning references. It states the following rule:
Once a reference is initialized to an object, it cannot be changed to refer to another object.
Iv wrote a short code (as asked to in an exercise) that is meant to prove this rule correct.
int y = 7;
int z = 8;
int&r = y;
r = z;
Can someone explain why this code compiles without any errors or warnings?
r = z does not change what r "points to." It assigns the value of z to the object pointed to by r.
The following code does the same thing as your code, but using pointers instead of references:
int y = 7;
int z = 8;
int* p = &y; // p points to y
*p = z; // assign value of z to the object pointed to by p (which is y)
It does not make the reference alias to something else but it changes the value of what r contains.
int&r = y;
ris reference to y
r = z;
changes value of y & r to value of z by assigning value of z to r & hence y.
int&r = y;
r = z;
It does NOT change the reference. Rather it changes the value pointed to by the reference variable. The reference variable is just yet another name of y. So r=z is equivalent to
y = z;
That is, r=z changes the value of y.
Reference variable cannot be reset to refer to another variable, in any way.
You're not changing the reference; you're setting a new value to the referred object. After this example you should note that y==8.
When you do r = z you are not reseating the reference, instead you are copying the value of z into y.
I faced the same issue when study <<thinking in c++> charpter11.
here is my understanding code: the second compile error seems can not be simulated. but can understand. you can draw a picture to see what x, y, z, and ref2 point to.
/**
Write a program in which you try to
(1) Create a reference that is not initialized when it is created.
(2) Change a reference to refer to another object after it is initialized.
(3) Create a NULL reference.
**/
#include <iostream>
using namespace std;
int main() {
// 1
//int& ref1; // compile error:
int x = 10;
int& ref2 = x;
cout << "x = " << x << endl;
cout << "ref2 = " << ref2 << endl << endl;
// 2
int y = 20;
ref2 = y; // 这里没有编译错误,ref2的指向并未改变,其指向的空间由10改变为20
cout << "ref2 = " << ref2 << endl;
cout << "x = " << x << endl;
cout << "y = " << y << endl << endl;
int z = 30;
ref2 = z;
cout << "ref2 = " << ref2 << endl;
cout << "x = " << x << endl;
cout << "y = " << y << endl;
cout << "z = " << z << endl;
// 3
//int& ref3 = NULL; // compile error:
return 0;
}