Using variables across functions - c++

Say I declare a variable in one function like so:
void i() {
int c;
}
how would I be able to do this in a different function?
void j() {
cout << c << endl;
}

Lets start with the basics:
in C++, default storage class of variables is auto.
What this means is that variables declared inside a block will only be available inside that block after you declare them.
a block is marked with the curly braces (loops, if statements, functions, etc)
void i() {
//c is not declared here and is unavailable
int c;
//c is available
for(int i=0; i<2; i++)
{
//c is also available here, because it is declared in larger scope
}
}
//c is not recognized here because it is declared only inside the scope of i()
void j()
{
int c; //this is variable c. it has nothing to do with the c that is declared in i()
for(int i=0; i<2; i++)
{
int d; //this variable gets created and destroyed every iteration
}
//d is not available here.
}
By default, a variable that is declared inside the body of a function, will live only inside that function scope after the point of declaration.
In your question you have not described how you want the two functions to communicate, thus it is difficult to point to a suitable approach.
If you want to pass the same value between functions you should read into argument passing and function return values. There is another way which is global variables, not recommended unless absolutely needed, but definitely something you need to learn.

void j(const int c)
{
std::cout << c << std::endl;
}
Then just call it from your function using:
j(c);

The best approach depends on what you actually do with c. Namely if c is not unique to an invocation of i() then you can use a global variable to get access it anywhere:
int c;
void i(){
c = c++; //uses c, pun intended
}
void j(){
cout << c << endl;
c++; //can change c
}
If a unique c is used every time i()is called, then you can define it in i() and have to pass it to j() from within i(), otherwise j() does not know where c is:
void i(){
int c;
j(c);
}
void j(int c){
cout << c << endl;
c++; //cannot change c in i()
}
Note that above c in i() and c in j() are not the same variable. If you change c in j() it will not be changed in i(), where as with the global approach it would be.
If want the variable to be unique to i() but accessible to j() you would instead pass the variable either by a pointer(not shown) or refence(shown below):
void i(){
int c=0;
j(c);
}
void j(int &c){
cout << c << endl;
c++; //can change c in i()
}
Note: The terminology here is rather casual, I didn't even use the word scope which you may want to learn more about.

The variable c wouldn't exist in the context where j is called, so you'd have to pass it on as a global variable or a return value.
int i(){
int c = 2;
return c;
}
int i() will return c, which can be passed on to other constructors.
void j(const int c){
std::cout << c << std::endl;
}
Or rather, call i inside of j.
void j(){
int cr = i();
std::cout << cr << std::endl
}

Related

Using variables in a function from another function

In function foo() there is a loop that iterates until it finds an optimum set of variables and determines that as the ideal set. The function only returns one variable, in order to pass a unit test.
In the next function bar(), I need to output all of the variables in function foo() as it iterates. First output the optimum set of variables, and then the rest of the possible variable sets seperately.
int foo(int a, int b) {
int c, d;
while ( etc. ) {
c = arithmetic_for_c;
d = arithmetic_for_d;
e = c + d;
}
return e;
}
int bar(a, b) {
cout << e;
cout << c << d;
}
This example is very simple, but you get the idea.
I have a feeling references (int&, string& etc) would help somehow, but I'm not sure how they would be used here.
I tried to put together a global array but that seemed to get a bit too complex for the scope of this assignment.
The loop is a necessity, but also seems to ruin any hope for variables or arrays in the global scope.
Unfortunately there are a number of things we haven't learned yet, so there is likely a solution I can't use yet.
Thoughts?
Thank you!
Unless you want to go really fancy (probably not within your reach, yet), foo() has to help bar() a little.
Since you want to show the end result first, then the intermediate data later, you will have to find some way of storing the intermediate states. You could do so, using arrays or lists and push the intermediate values into them.
But another, probably shorter option is, to just store the intermediate output.
You know how to use std::cout by now, which prints output to the console.
It is of type std::ostream. And next to output to a console (or file etc.), the c++ standard library also allows to output to a string.
So, for your use case to work, you create such a string stream, then call bar and give it as output stream the string stream.
At the end of your calculations, you call bar with the regular output stream to print the end result, then, you output the string of the string stream to the regular output stream.
It sounds more convoluted, than it actually is, if you see it in code:
#include <iostream>
#include <sstream>
void bar(int a, int b, int c, int d, int e, std::ostream& os) {
os
<< "a: " << a
<< " b: " << b
<< " c: " << c
<< " d: " << d
<< " e: " << e
<< std::endl;
}
int foo(int a, int b, std::ostream& os ) {
std::ostringstream ossteps;
int c= 0;
int d= 1;
int e= 42;
while (c < 10) {
bar(a,b,c,d,e,ossteps);
c++;
d += c*c;
e = (a * b) - d;
}
bar(a,b,c,d,e,os);
os << ossteps.str();
return e;
}
int main (int argc, const char* argv[]) {
int efinal = foo(1,2, std::cout);
return 0;
}
If I'm not mistaken, this is not really possible in C++, as the variables are declared in the scope of the function foo, and cannot be accessed from a different scope. But you can always use something like this:
Pass by reference (out parameters):
#include <iostream>
// Declaring bar earlier as it has to be accessed by foo
int bar(int& c, int& d) {
int e = 0; // Declaring and initializing variable e
int count = 0;
// Loop
while (count < 10) {
c++;
d += 2;
e = c + d;
count++;
}
return e; // Return variable e
}
int foo(int a, int b) {
int c, d;
c = a, d = b; // setting c = parameter a, d = parameter b
int e = a + b;
std::cout << c << d << std::endl; // Printing variables c and d
std::cout << e << std::endl; // Printing variable e
e = bar(c, d); // Calling bar function. Also this function increments c by 10 and d by 20.
std::cout << c << d << std::endl; // Printing variables c and d
std::cout << e << std::endl; // Printing variable e
return e; // Return variable e
}
int main() {
foo(10, 20); // Calling function 'foo'
}
This is just an example.
The CPU is performing one thread at a specific time. So it can only perform the code in function foo or the function bar, but never both. The scope of the variables in the function are called local or auto variables. They are valid only in the context of the execution of the function. At language level you will say they go out of scope at the closing } bracket. Technically, the memory for the variable is allocated temporarily while entering the function and automatically released on exit. It's just a memory location on the stack. The live time of the variable ends at the end of scope.
So, you must always look at the scope of a variable. You can't access anything temporarily allocated on a different function's stack. The game changes if one function calls another. You can pass a reference from the calling function to the called function, but not the other way.
int foo(int a, int b, int& c, int& d) {
while ( etc. ) {
c = arithmetic_for_c;
d = arithmetic_for_d;
e = c + d;
}
return e;
} // scope of the reference c and ends here,
// but not the scope of the referenced variables.
int bar(a, b) {
int c, d;
// here you define the role of calling function and called function.
int e = foo(a, b, c, d);
cout << e;
cout << c << d;
} // scope of c and d ends here.

Function that does same things for different parameters

I have two functions that do the same thing: they add two numbers. One adds two numbers which are members of the class, the other adds numbers given by the user, outside the class.
Is there any way to write one single function that adds two numbers and checks whether the arguments are user input or class members?
void myclass::add(){
cout<<this->a+this->b;
}
void myclass::add(int a,int b){
cout<<a+b;
}
While you cannot really do it in a single function the common approach would be to write the more flexible of the two and use the other one just as a dispatcher:
void myclass::add(int a, int b) {
std::cout << (a+b);
}
void myclass::add() {
add(a,b);
}
Now, there are a different number of smells in this code... a function name reused to act on members or only inputs is one (a function that does not touch the object's state already smells at it not being a member, or being a static one). Printing inside a function called add (should it not return the values?)...
Disclaimer : I don't encourage such coding.
Ok, here's a method
void myClass::Add(int& a, int& b)
{
if (&a==&this->a)
{
std::cout << this->a + this->b
} else {
std::cout << a+b;
}
}
Ofc , things like myClass->Add(10,4) won't work... you will need some stack variables to hold the 10 and 4 variables.
So you want a single function that can have two different parameters? It isn't possible.
void myclass::add(int a, int b)
{
cout << a + b << endl;
}
Is what you want; but you can overload the function:
void myclass::add()
{
cout << memberA + memberB << endl;
}
In my opinion, this is a much better solution than having a single function that checks whether the variables are members or not; it makes your code readable. Don't be afraid to overload functions - it's one of those things that makes C++ awesome. I've created a class to demonstrate this:
class myClass
{
public:
myClass() : memberA(0), memberB(0) {}
~myClass() {}
void setNumbers(int a, int b)
{
memberA = a;
memberB = b;
}
void add(int a, int b)
{
cout << a + b << endl;
}
void add()
{
cout << memberA + memberB << endl;
}
private:
int memberA;
int memberB;
};
int main()
{
myClass m;
m.setNumbers(1, 2);
m.add();
return 0;
}
I've tested the add function with and without parameters and they both output the same result. The former because I used a setNumbers(..) function. Effectively, your first scenario of having two functions is the most apt solution to begin with.
In you realy wanted a single function, the way to do it is with optional default parameters.
Your declaration will be
void add(optional<int> a = optional<int>(), optional<int> b = optional<int>() );
Then in your implementation:
a ? a.get() : this->a
A benefit of this approach is that you can mix members and parameters. For example:
obj.add(1);
obj.add(optional<int>(), 2);

Order of evaluation of names declared in class

There is this code:
#include <iostream>
const int c = 3;
struct A {
static int f() { return c; }
static const int c = 2;
};
int main() {
std::cout << A::f() << std::endl; // 2
return 0;
}
How does it happen that variable c defined inside class A is used in function f instead of variable c defined in global scope although global variable c is declared first?
It does not matter which variable is declared first: if a class has a variable with the same name in it, that variable trumps the global variable. Otherwise you could get existing code in a lot of trouble simply by declaring a global variable with a name of one of its member variables!
Of course your class can use scope resolution operator to reference the global c directly:
static int f() { return ::c; }
Now your program will print 3 instead of 2.
Is not a question of declaring order but of variable scope, the used variable are searched before in the current method/function after in the class/struct and a the and in the global context,
example:
#include <iostream>
const int c = 3;
struct A {
static void print() {
int c = 4
std::cout <<"Method Scope:"<< c << std::endl; // 4
std::cout <<"Class/Struct Scope:"<< A::c << std::endl; // 2 here you can use alse ::A::c
std::cout <<"Global Scope:"<< ::c << std::endl; // 3
}
static const int c = 2;
};
struct B {
static void print() {
std::cout <<"Method Scope:"<< c << std::endl; // 2
std::cout <<"Class/Struct Scope:"<< B::c << std::endl; // 2 here you can use alse ::A::c
std::cout <<"Global Scope:"<< ::c << std::endl; // 3
}
static const int c = 2;
};
struct C {
static void print() {
std::cout <<"Method Scope:"<< c << std::endl; // 3
//std::cout <<"Class/Struct Scope:"<< C::c << std::endl; //is inpossible ;)
std::cout <<"Global Scope:"<< ::c << std::endl; // 3
}
};
int main() {
A::print();
B::print();
C::print();
return 0;
}
imagine that you have long code which uses many variables, do you want them to be called instead these from a class to which function belongs? stating:
a or b
in class means
this->a
this->b
and if you want global variable to be visible you have to use it like
::a or ::b inside this function, so via:
static int f() { return ::c; }
From the standard docs, Sec 3.3.1
Every name is introduced in some portion of program text called a declarative region, which is the largest part of the
program in which that name is valid, that is, in which that name may be used as an unqualified name to refer to the
same entity. In general, each particular name is valid only within some possibly discontiguous portion of program text
called its scope. To determine the scope of a declaration, it is sometimes convenient to refer to the potential scope of
a declaration. The scope of a declaration is the same as its potential scope unless the potential scope contains another
declaration of the same name. In that case, the potential scope of the declaration in the inner (contained) declarative
region is excluded from the scope of the declaration in the outer (containing) declarative region.
this means that the potential scope is same as the scope of the declaration unless another (inner) declaration occurs. If occurred, the potential scope of the outer declaration is removed and just the inner declaration's holds, so your global variable is hidden.

Dependent variables in C++?

I tried asking before but I wasn't very clear so I'm re-asking it.
I want to have a variable that depends on the value of another variable, like b in this example:
int main(){
int a;
dependent int b=a+1; //I'm just making this up
a=3;
cout << b; //prints 4
a=4;
cout << b; //prints 5
}
Of course, this does not exist in C++, but this is what I want.
So instead I tried making a function:
int main(){
int a;
int b(){ return a+1; } //error
a=3;
cout << b(); //would print 4 if C++ allowed nested functions
a=4;
cout << b(); //would print 5 if C++ allowed nested functions
}
The above doesn't work because C++ doesn't allow nested functions.
I can only make functions outside of main(), like this:
int b(){
return a+1; //doesn't work because a is not in scope
}
int main(){
int a;
a=3;
cout << b();
a=4;
cout << b();
}
But this does not work because a is not in the same scope as b(), so I would have to pass a as a parameter and I don't want to do that.
Are there any tricks to get something similar to a dependent variable working in C++?
What you need is a closure. If you can use C++ 0x features, you are in luck. Otherwise, you can define one manually:
#include <iostream>
using namespace std;
struct B
{
const int & a;
B(const int & a) : a(a) {}
// variable syntax (Sean Farell's idea)
operator int () const { return a + 1; }
// function syntax
int operator () () const { return a + 1; }
};
int main()
{
int a;
B b(a);
a = 3;
cout << b << '\n'; // variable syntax
a = 4;
cout << b() << '\n'; // function syntax
}
You can also define B inside main, but some compilers would not like it.
The C++ 0x lambda syntax looks like this:
auto b = [&]() { return a + 1; }
The [&] means that the lambda captures local variables by reference.
If you're using C++0x (GCC 4.5+, Visual C++ 2010), you can use lambdas:
int a = 5;
auto b = [&a]{ return a + 1; };
std::cout << b() << std::endl;
Depending on what you're doing, though, there are probably cleaner solutions - possibly some variation of the classic "method that takes in 'a' and returns 'b'"
You could define a class that had a member a, and then a function b() that returned the value of a+1. A basic implementation would be something like:
class Dependent {
public:
Dependent(void) { m_value = 0; }
void set(int value) { m_value = value; }
int b(void) { return(m_value + 1); }
private:
int m_value;
};
int main(){
Dependent a;
a.set(3);
cout << a.b();
a.set(4);
cout << a.b();
}
You could add operator overloading as appropriate to make it work more like normal integers if you so desired.
This is possible if you use lambda functions (c++0x), because they can capture local variables.
Example:
int main()
{
int a;
auto f = [&] () -> int { return a + 1; };
a = 3;
std::cout << f() << std::endl;
a = 4;
std::cout << f() << std::endl;
return 0;
}
Result:
4
5
(See http://ideone.com/MlzX7 for proof)
A simple approach is to use pre-processor macros, nothing C++ specific about it though:
#define b ((a)+1)
int main(){
int a;
a=3;
cout << b;
a=4;
cout << b;
}
#undef b
Are you OK using C++0x ? if yes,
int main()
{
int a = 10;
auto b = [&a]() -> int { return a + 1; };
cout << b() << endl;
}
Since, it is not tagged with c++0x, you can use nested classes instead of nested functions. This column from Herb sutter would help you for existing c++. http://www.gotw.ca/gotw/058.htm
The above doesn't work because C++ doesn't allow nested functions.
You can simulate that using nested structure. In C++0x you can make use of lambda function, which provides the same means of function inside function.
Define a class called LinkedInt or something that behaves like an int, but has a RelatedTo relationship on itself and an additional member that is a function pointer to the function to evaluate when computing the integer's value. Pretty straightforward. Let me know if you need some pointers on the coding.
The short answer is that OOP is more than enough to bury this problem.
I want to have a variable that depends on the value of another
variable, like b in this example:
I see you just need a reference variable:
int a;
int &b =a;
a=10;
cout << b; // 10
Why C++0x lambdas do come for this, I dont understand.

Assigning value passed by reference to a member variable (in C++)

I am trying to wrap my head about scope in C++. Please consider the following:
class C
{
int i_;
public:
C() { i_ = 0;}
C(int i) { i_ = i; }
C(const C &c) {
i_ = c.i_;
cout << "C is being copied: " << i_ << endl;
}
int getI() { return i_; }
~C() {cout << "dstr: " << i_ << endl;}
};
class D
{
C c_;
public:
void setC(C &c) { c_ = c; }
int getC_I() { return c_.getI(); }
};
void Test(D &d)
{
C c(1);
d.setC(c);
//here c is going out of scope, surely it will be destroyed now?
}
int main()
{
D d;
Test(d); //this sets value of c_ to the local variable in Test.
//Surely this will be invalid when Test returns?
int ii = d.getC_I();
cout << ii << endl;
}
Running this program outputs:
dstr: 1
1
dstr: 1
Apparently, the first destructor call occurs in Test, and the other when program terminates and d is destroyed.
So my question is: Where was c copied? Is there fault with my reasoning? And general point I am trying to ask: is it safe to have a member function that takes a reference to an object and then stores it in a member variable?
Many thank for your help.
Your code is fine as it stands right now. D::c_ is of type C rather than C &. Your SetC takes a reference to a C, and assigns the value referred to by that reference to C::c_, so what you have is an entirely separate C object that has the same value. Since you created d with automatic storage duration in main, it and c_ which is part of it remain valid until you exit from main.
Where was c copied?
When you do c_ = c;Where was c copied?, you're calling operator= on c_ which will copy the contents of c to c_.
If c_ were a also reference, nothing would be copied, and the program would cause an error like you expect it to.
C is getting copied here:
void setC(C &c) { c_ = c; }
If you want to store a reference then your member variable c_ should also be a reference. If you are storing a reference then you'll have to be careful with the lifetime of the variable you're passing in.