#include <iostream>
using namespace std;
int x=24 ;
int main()
{
int x=0;
{
int x=5 ;
::x= x+2 ;
}
cout<<::x<<endl ;//first
cout<<x<<endl ; // second
return 0;
}
in this simple example i'm using code block and i know i can modify the global variables using Scope resolution operator.
and i modify the global variable in this example but i wonder if there is a way to modify the variables in specific scope like main function (not necessary the( Scope resolution operator) way )
that mean in this example i need the first output is 24 and the next one 7 .
sorry for my english i hope to understand the question
There are no means to access variables from a specific scope in C++.
If you declare an object or a variable in the inner scope with the same name as an object or a variable in the outer scope, then for all intents and purposes that outer scope's object or variable is not directly visible in the inner scope.
If you already have a pointer or a reference to the outer scope's object, of course, you can still access it indirectly. You just cannot access it directly.
This is a fundamental concept of C and C++; but many other programming languages share the same analogous concept.
The scoping rules of C++ are textual and AFAIK you can't do this, as you can't go putting namespaces inside of functions. But introducing a reference with a unique name may help you as a workaround if you find yourself in a bind like this:
#include <iostream>
using namespace std;
int x = 24;
int main()
{
int x = 0;
int & main_outer_x = x;
{
int x = 5;
main_outer_x = x + 2;
}
cout << ::x << endl; //first
cout << x << endl; // second
return 0;
}
That gives you:
24
7
That shouldn't cost any more memory in your generated code, and lets you keep the outer name untouched. Still, likely to be confusing and error prone if you're purposefully having a name collision within a function. This is abstract code so it's hard to criticize, but most concrete code with such a pattern should probably be done another way.
Related
This question already has answers here:
variable declaration within the while loop C/C++
(5 answers)
Closed 5 years ago.
Why does this code cause an infinite loop:
#include <iostream>
using namespace std;
int main() {
int y = 5;
while (y < 6) {
int y = 7;
cout << y << endl;
}
}
yet removing the "int" in the while statement makes it run once normally?
(
#include <iostream>
using namespace std;
int main() {
int y = 5;
while (y < 6) {
y = 7;
cout << y << endl;
}
}
)
In this loop:
while (y < 6) {
int y = 7;
cout << y << endl;
}
The inner y is not accessible in the condition test.
If you remove the int in the loop, you're simply assigning a new value to the variable defined outside while, thus terminating it.
Look up Scope on CppReference.
The behaviour you have observed is called shadowing.
This means that a variable is "shadowed" by another variable in an inner scope.
(iBug has already provided a link to the C++ scope rules)
The outer scope (in your case while(y < 6)) can not access the inner scope (in your case int y = 7;) and vice versa. Both have the same name, but they are completely separate variables in separate scopes.
This is a very common source for errors (you also find a lot of them here) and doesn't only happen with loops and other scope brackets, but also very often with class members. Imagine a class:
class MyClass {
int a;
public:
void getA( int a ) { return a; }
};
getA() defines a parameter a, which shadows the class member a. This is at least bad style, but even more probable a source of errors. We don't know - did you want to return the member a or did you really mean the parameter? So this should be avoided.
Here's a real life example on Stackoverflow - see my comment below the question (regarding the 3rd constructor)
Possibilities to avoid these kind of errors are:
Use highest possible compiler warnings and perhaps even warnings as errors. Compilers can warn about those kind of shadowing issues.
Use a name scheme. A common scheme is members with a m, m_ prefix, a _ suffix and the like. If the member name in the MyClass would have been m_a, this would have reduced confusion. Of course this doesn't help in your example, but it's a good idea nevertheless.
This question already has answers here:
variables declaration with same name C++
(5 answers)
Closed 5 years ago.
I understand that two variable can be declared of same name in two distinct function.
how can we declare a variable within a function which is already declared in the global scope?
This is called variable shadowing. In C++, you can use scope resolution operator :: to refer to global variable from inside a block. The C language does not have this, however you may use the following technique to access global variable as well:
#include <stdio.h>
int a = 100;
int main(void)
{
int a = 200;
printf("%d\n", a); // prints 200
// anonymous block used to refer to global a
{
extern int a;
printf("%d\n", a); // prints 100
}
return 0;
}
Even this is possible, be wary, that it may confuse other programmers, i.e. it violates "Don't be clever" principle.
For C++ you can always use the resolution operator to specify what scope you are talking about (::)
However in C the rule is that the variable in the context of the more specific scope is used.
int num = 5;
int main()
{
printf("%d\n", num);
int num = 3;
printf("%d\n", num);
return 0;
}
Prints
5
3
Scope of a variable is the part of he code where that variable is visible.
Therefore a global variable is visible everywhere but a local variable is visible only to a particular section of code.
#include <iostream>
using namespace std;
int a=9;
int main()
{
int a =8;
cout<<a<<endl;
cout<<::a;
return 0;
}
In the above c++ code first output is 8 whereas second is 9.
Here both variables were visible in the code but using scope resolution operator you can decide which variable you actually want.
Said in simple terms, if multiple variables in a program have the same name, then there are fixed guidelines that the compiler follows as to which variable to pick for the execution. I'll go over them all in an example below.
Global variables, as the name suggests are declared outside of any function and are accessible in any part of the code. However, in the event of another variable with the same name as the global one, the local variable would get the higher "preference" for the part of the code that comes after it is declared.
For example,
int num = 25;
class Print
{
int num;
Print();
};
Print::Print()
{
num = 98;
}
void PrintNumber(void)
{
int num = 12;
}
int main(void)
{
cout << num << endl;
int num = 34;
cout << num << endl;
PrintNumber();
Print object;
cout << object.num << endl;
}
I've tried to cover every possible scenario, please don't hesitate to inform me if I missed any scenario out. Anyways, the result of this program would be:
25
34
12
98
The first one is the global one; since the variable num of the class Print and the function PrintNumber() is localized to the object of the class and that function respectively, only the global variable is accessible here. Same for the second number, except a local variable with the same number num has a a higher privilege, so it is given a higher accessibility than the global variable (mind my erroneous English, sorry for that). Then when the PrintNumber() function is invoked, it prints the num of that local variable. Finally, an object of class Print will output the value stored in the num of that class.
Hope this answers your question.
I'm trying to create a loop that will will create a new variable but also change the name of the variable, such as increasing in value, automatically. Not sure if this is possible because you cant have dynamic variables?
if (cin.get() == '\n')
{
m ++; // Add an integer to m
string (1 + m); //Trying to name the string the value of m + 1, i.e 3
cin.ignore():
getline(cin, (1 + m))
myfile << (1 + m) << endl;
}
That is my current code which is full of errors but hopefully readable enough to gain an understanding of what I'm trying to do.
Bad title, don't know what else to call it.
You're misunderstanding C++ if you try to "rename a variable".
C++ is a compiled language in which the names of the variables only exist in your source code as a means of handling them, but not in the compiled program.
You hence can't also create a variable with a specific name at runtime -- variable names simply don't exist then.
You probably want some kind of container that maps values to keys, think of a dictionary, where you can say "for this integer value 12, I store the string monkey" or so. Have a look at std::map.
Now, you're really not making much sense right now; and try to do things that aren't really the way C++ works for anyone who learned it in a ordered manner. I'd really recommend getting a C++ book or tutorial and start with that. It's going to turn out to safe you a lot of time! Here's a list of recommended C++ books and ressources.
You can't. It's not possible in C++.
To declare and initialize a variable in each iteration is however possible:
for (int i = 0; i != 10; ++i) {
int var = i; // Declare 'var' and assign value of 'i' to it.
} // 'var' object goes out of scope and is destroyed
Names are visible from the point where they are declared until the end of the scope in which the declaration appears. Names have scope and Objects have lifetimes.
The closest thing to "renaming" in C++ would be declaring a reference of the "old named" variable with the new name.
int a = 2;
int &b = a;
//you can now call either `b` or `a` to get the value
Creating new variables on the fly is not possible. The correct insert any compiled language name here way of doing it is by pushing values into a container (array, map, stack..etc). With maps, you can do something similar to what you want, but it's different one only "maps" a string to a value.
#include <map>
#include <string>
#include <sstream> //for int to string conversion
std::string stringify(int val)
{
std::stringstream ss;
ss << n;
return ss.str();
}
int main()
{
std::map<std::string, int> values;
for (int i = 0; i < 10; i ++){
values[stringify(i)] = i*100;
}
std::cout << values["1"]; // prints 100
std::cout << values["9"]; // prints 900
return 0;
}
If there is a global variable and the function has a parameter with the same name, and desired result is the sum of the local and global variable, how can we refer the global function in this particular situation? I know its not good idea to do so. But asking just for curiosity.
int foo = 100;
int bar(int foo)
{
int sum=foo+foo; // sum adds local variable and a global variable
return sum;
}
int main()
{
int result = bar(12);
return 0;
}
By far the best choice is to rename the function parameter so it does not conflict with the global variable, so there is no need for circumventions.
Assuming the rename option is not acceptable, use ::foo to refer to foo at the global scope:
#include <iostream>
int foo = 100;
int bar(int foo)
{
int sum = foo + ::foo; // sum adds local variable and a global variable
return sum;
}
int main()
{
int result = bar(12);
cout << result << "\n";
return 0;
}
Collisions between local and global names are bad ā they lead to confusion ā so it is worth avoiding them. You can use the -Wshadow option with GCC (g++, and with gcc for C code) to report problems with shadowing declarations; in conjunction with -Werror, it stops the code compiling.
Use ::foo - but REALLY don't do that. It will confuse everyone, and you really shouldn't do those sort things. Instead, rename one or the other variable. It's a TERRIBLE idea to use the :: prefix to solve this problem.
Best practice is to always name global variables with a leading lower case "g" as in gX gY.
It is never clear what you should name your variables at the beginning though.
::foo . That's a cool trick.
The below code give the compilation error
namespace X{
int i;
}
void f(){
int i;
using X::i; //compile error 'iā is already declared in this scope
}
But if i replace this line with using namespace X, it compiles fine.
Can someone help understand differences.
Also in the modified code below, I was expecting the output for X::I to be 100 in all places, but it is not.
May be I have misunderstood the namespace concept ?
namespace X{
int i;
}
void f(){
int i=1;
cout << "local I " << i << endl; // prints 1 OK
using namespace X;
i=100;
cout << "X::i " << i << endl; // prints 100 OK.
cout << "X::i " << X::i << endl; // prints 10 why ?
}
main(){
using namespace X;
i=10;
f();
cout << "X::i " << i << endl; //prints 10 why ?
}
Thanks for any help to make me understand this.
In main():
using namespace X;
i = 10;
This sets X::i to 10.
prints 10 why?
That's ^^ why.
Also, in f(): you have another local variable named i that shadows X::i, that's why i resolves to 1 and 100, respectively, and you can only access the other variable in the X namespace by explicitly specifying its namespace.
When you say 'using namespace X'...
if the variable 'i' is defined in X, then, for all references to the variable 'i', the compiler replaces it with 'X::i'. So in main(), when you say i=10, it's setting X::i to 10.
In f()...
you create a NEW variable called i. This is different from X::i. You set i to 1. Then, you begin using namespace X. However, there is a naming conflict--when you say 'i', should it use the local 'i', or X::i? The C++ compiler handles this such case by identifying the variable 'i' with the LOCAL i. Because there is already an i defined in the function, it cannot introduce another i--the i in the namespace. So, in order to reference X::i, you have to explicitly say 'X::i'. Otherwise it thinks you're talking about the LOCAL i.
In the first example, when you say using X::i, you're not giving the compiler much of a choice. You're saying < I WANT TO CALL X::i 'i' >. However, it can't do this--because there's already an 'i' defined. Forcing the compiler to do this would result in two different variables having the same name--which cannot happen.
Hopefully this clarified things a bit. Comment with additional questions.
The using X::i Statement introduces a particular name into the scope. Apparently, the name i was already used so you will not be able to use it again.
Actually, namespaces are used to avoid possible name-clashing. With such short names, namespaces are actually overkill.