In my program (this is only a short version), I have a struct that has 9 members (airplanes) which all have the same variables.
struct FlightP {string FLID; int altitude; int heading; flightMode; } ArrP_1, ArrP_2;//1-9 etc
If I want to change for example the altitude of members ArrP_1 and ArrP_2 I did it like so:
int main(){
ArrP_1.altitude = 10000;
ArrP_2.altitude = 10000;
}
But is there a way to use a function like that:
void ALtChange(FlightP flight_p){
flight_p.altitude = 12000;
}
int main(){
ALtChange(ArrP_1);
ALtChange(ArrP_2);
//If I have to change multiple parameters in multiple members at the same time this function would make things easier.
}
Somewhy this function doesn't do anything. Is the function wrong or what should I do differently?
Somewhy this function doesn't do anything.
Your function modifies the function argument that is local to the function.
In order to modify a variable from another scope, you can use indirection: Use a reference argument.
Instead of modiying the object in the function, another approach is to write a function that returns a ALtChange object, and you can assign the result to a variable to modify it.
It's like #Jonnhy Mopp said, pass it by reference like so:
#include <iostream>
#include <string>
using namespace std;
struct FlightP {string FLID; int altitude; int heading; int flightMode; } ArrP_1, ArrP_2;//1
void ALtChange(FlightP& flight_p) { flight_p.altitude = 12000; }
void print_altitude(const FlightP& flight) { std::cout << flight.altitude << std::endl; }
int main(){
ArrP_1.altitude = 10000;
ArrP_2.altitude = 10000;
ALtChange(ArrP_1);
ALtChange(ArrP_2);
print_altitude(ArrP_1);
print_altitude(ArrP_2);
}
Related
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 months ago.
I would like to know how I can make a function's variable public to other functions.
Example:
void InHere
{
int one = 1; // I want to be public
}
int main()
{
InHere(); // This will set int one = 1
one = 2; // If the variable is public, I should be able to do this
return 0;
}
Does anyone know how to do this? The only things I find when searching is for classes, as you can see nothing is in a class and I don't want them to be in one.
Any help is really appreciated!
A variable defined locally to a function is generally inaccessible outside that function unless the function explicitly supplies a reference/pointer to that variable.
One option is for the function to explicitly return a reference or pointer to that variable to the caller. That gives undefined behaviour if the variable is not static, as it does not exist after the function returns.
int &InHere()
{
static int one = 1;
return one;
}
void some_other_func()
{
InHere() = 2;
}
This causes undefined behaviour if the variable one is not static since, as far as the program as a whole is concerned, the variable only comes into existence whes InHere() is called and ceases to exist as it returns (so the caller receives a dangling reference - a reference to something that no longer exists).
Another option is for the function to pass a pointer or reference to the variable as an argument to another function.
void do_something(int &variable)
{
variable = 2;
}
int InHere()
{
int one = 1;
do_something(one);
std::cout << one << '\n'; // will print 2
}
The downside is that this only provides access to functions CALLED BY InHere(). Although the variable does not need to be static in this case, the variable still ceases to exist as InHere() returns (so if you want to combine option 1 and option 2 in some way, the variable needs to be static)
A third option is to define the variable at file scope, so it has static storage duration (i.e. its lifetime is not related to the function);
int one;
void InHere()
{
one = 1;
}
void another_function()
{
one = 2;
}
int main()
{
InHere();
// one has value 1
some_other_function();
// one has value 2
}
A global variable can be accessed in any function that has visibility of a declaration of the variable. For example, we could do
extern int one; // declaration but not definition of one
int one; // definition of one. This can only appear ONCE into the entire program
void InHere()
{
one = 1;
}
And, in other source file
extern int one; // this provides visibility to one but relies on it
// being defined in another source file
void another_function()
{
one = 2;
}
int main()
{
InHere();
// one has value 1
some_other_function();
// one has value 2
}
Be careful with that though - there are numerous down-sides of global/static variables, to the extent they are usually considered VERY BAD programming technique. Have a look at this link (and pages linked to from there) for a description of some of the problems.
Just set the variable as a global variable. Then you can access it from other functions.
int one;
void InHere()
{
one = 1; // I want to be public
}
int main()
{
InHere(); // This will set int one = 1
one = 2; // If the variable is public, I should be able to do this
return 0;
}
if you want it inside a class, then try the code below
#include <iostream>
using namespace std;
class My_class
{
// private members
public: // public section
// public members, methods or attributes
int one;
void InHere();
};
void My_class::InHere()
{
one = 1; // it is public now
}
int main()
{
My_class obj;
obj.InHere(); // This will set one = 1
cout<<obj.one;
obj.one = 2; // If the variable is public, I should be able to do this
cout<<obj.one;
return 0;
}
I want to be able to pass a struct member into a function:
struct threeBuckets {
int bucketA;
int bucketB;
int bucketC;
};
threeBuckets allCombinations[512000] = {{0,0,0}};
int totalCombinations = 1;
int counter = 0;
//note that pourer, receiver, and other are one of the struct members (bucketA, bucketB, and bucketC)
void pour(pourer, receiver, int receiverCap, other) {
int finalTriple[3];
allCombinations[totalCombinations].bucketA = allCombinations[counter].bucketA;
allCombinations[totalCombinations].bucketB = allCombinations[counter].bucketB;
allCombinations[totalCombinations].bucketC = allCombinations[counter].bucketC;
allCombinations[totalCombinations].receiver = allCombinations[totalCombinations].receiver + allCombinations[counter].pourer;
allCombinations[totalCombinations].pourer = 0;
if (allCombinations[totalCombinations].receiver > receiverCap) {
allCombinations[totalCombinations].pourer = allCombinations[totalCombinations].pourer + allCombinations[totalCombinations].receiver - receiverCap;
allCombinations[totalCombinations].receiver = receiverCap;
}
finalTriple[0] = allCombinations[totalCombinations].bucketA;
finalTriple[1] = allCombinations[totalCombinations].bucketB;
finalTriple[2] = allCombinations[totalCombinations].bucketC;
//some more irrelevant code
}
As I've hopefully made clear, the parameters pourer, receiver, and other are bucketA, bucketB, and bucketC (in no particular order, the order does change depending on when I call the function.) There are several places where I want to modify the instance
allCombinations[totalCombinations].pourer
for example. How do I use the struct member as a parameter, and what type do I use to specify it?
Note: I'm mostly a beginner and am new to StackOverflow, so if anything else I'm doing is wrong, please feel free to tell me.
Note 2: If any of you do or have done USACO, you might recognize this problem as the milk3 training gateway problem. This might aid you if you don't know what I'm doing here.
It sounds like you need to use pointer to member variable for the argument types in pour.
void pour(double threeBuckets::(*pourer) ,
double threeBuckets::(*receiver),
int receiverCap,
double threeBuckets::(*other)) {
...
}
In the function, change the use of
allCombinations[totalCombinations].pourer
allCombinations[totalCombinations].receiver
allCombinations[totalCombinations].other
by
allCombinations[totalCombinations].*pourer
allCombinations[totalCombinations].*receiver
allCombinations[totalCombinations].*other
respectively.
At the point of calling the function, use:
pour(&threeBuckets::bucketA,
&threeBuckets::bucketB,
0, // Any appropriate value
&threeBuckets::bucketC);
Another option that is worth considering is:
Change threeBuckets to use an array.
Change the arguments to pour to be indices to the array.
struct threeBuckets {
int buckets[3];
};
void pour(int pourerIndex ,
int receiverIndex,
int receiverCap,
int otherIndex)) {
...
}
Then, instead of using
allCombinations[totalCombinations].pourer
allCombinations[totalCombinations].receiver
allCombinations[totalCombinations].other
use
allCombinations[totalCombinations].buckets[pourerIndex]
allCombinations[totalCombinations].buckets[receiverIndex]
allCombinations[totalCombinations].buckets[otherIndex]
Of course, change the call to use indices.
pour(0,
1
0, // Any appropriate value
2);
I want to implement a function that can print out the value of one member variable (for example, 'aa') of struct ('Data') by it's name.
I try to use the macro definition as follows, but failed.
Is there a simple way to implement it?
#include <string>
#include <iostream>
using namespace std;
struct Data
{
int aa;
int bb;
int cc;
Data(): aa(1),bb(2),cc(3) {};
};
#define Param(a,b) a.##b
void Process(Data& data, const string& name)
{
cout << Param(data, name) << endl;
}
void main()
{
Data data;
Process(data, "aa");//I want print the value of Data.aa
Process(data, "bb");//I want print the value of Data.bb
Process(data, "cc");//I want print the value of Data.cc
}
This is not possible in C++.
This kind of usage is generally seen in scripting languages.
In C++ the variable names are constructed at compile time.
Your original code sample makes no sense to me because if you call Param(name) then the compiler has to know what instance of Data it has to use to determine the value of the member variable you want to get the value of (but I'm neither an expert using macros nor do I like them very much).
I tried to solve your problem using the following approach:
struct Data
{
int aa;
};
#define GetMemberValue(d, n) d.##n
int main()
{
Data d;
d.aa = 3;
int i = GetMemberValue(d, aa);
}
At least this approach returns the right result in this case.
Another thing is that you stated that you cannot call the member variables directly i.e. data.aa so you might run into the same issue using the macro. It's just a guess as I don't know the original code you're using.
When i assign value to s.rollno in this way it doesnot work
#include<stdio.h>
struct student{
int rollno;
int marks;
}s ;
s.rollno = 2;
int main(){
printf("%d",s.rollno);
}
BUt if i assign value to s.rollno in main it works
#include<stdio.h>
struct student{
int rollno;
int marks;
}s ;
int main(){
s.rollno = 2;
printf("%d",s.rollno);
}
you cannot write
s.rollno = 2;
in global scope, as a separate statement. All the statements needs to appear inside some function , which can execute them.
However, you can initialize the value at the time of definition, like
struct student {
int rollno;
int marks;
} s = {.rollno = 2};
You can create a global variable outside of a function scope like this:
int a;
int main() {
a = 5;
}
But you cannot set it like you do. This is because of the difference between runtime and compile time. Global variables are created and set to memory and this is determined at compile time. But code like a=5 above is performed at run time. Imagine this situation:
int a;
a = somestruct.somefunction();
Without a function to run this in, how can we be sure what a is? Things done outside the scope of a function cannot occur at run time.
This has defeated me. I want to have a static class variable which is a pointer to a (non-static) member function. I've tried all sorts of ways, but with no luck (including using typedefs, which just seemed to give me a different set of errors). In the code below I have the static class function pointer funcptr, and I can call it successfully from outside the class, but not from within the member function CallFuncptr - which is what I want to do. Any suggestions?
#include <stdio.h>
class A
{
public:
static int (A::*funcptr)();
int Four() { return 4;};
int CallFuncptr() { return (this->*funcptr)(); }
// doesn't link - undefined reference to `A::funcptr'
};
int (A::*funcptr)() = &A::Four;
int main()
{
A fred;
printf("four? %d\n", (fred.*funcptr)()); // This works
printf("four? %d\n", fred.CallFuncptr()); // But this is the way I want to call it
}
Try this instead:
#include <iostream>
class A {
public:
typedef int (A::*AMemFn)();
static AMemFn funcptr;
int Four() { return 4; }
int CallFuncptr() { return (this->*funcptr)(); }
};
A::AMemFn A::funcptr = &A::Four;
int main()
{
A fred;
std::cout << "four? " << fred.CallFuncptr() << std::endl;
}
jweyrich has a nice looking work around (and I suggest you use it), but I thought I'd elaborate on what the real problem in the code is:
Your problem is this line:
int (A::*funcptr)() = &A::Four;
This is defining a global variable called funcptr that is of the right type, rather than A::funcptr.
What you need is this mess:
int (A::*(A::funcptr))() = &A::Four;
This ugly mess is why I suggest you go down the typedef path to get a nice looking version like jweyrich's solution.
A static variable is not a member of a particular object -- it can only be accessed through the classes namespace. CallFuncptr should be rewritten:
int CallFuncptr() { return (*funcptr)();
which I think should work, since this function can access functions in A's namespace without specifying it.
Also, function pointers are more of a C construct than C++. You can access the static variable outside the class with the code:
A::CallFuncptr
since CallFunctptr just resides in A's namespace