The code:
int i;
struct st
{
int m;
}st_t[2];
void foo()
{
i = 4;
st_t[2] =
{
{10},{20}
}; // it's wrong !!!! but I don't know how to do.
}
int main()
{
foo();
cout<<i<<endl; // will output 4;
cout<<st_t[0].m<<endl; // this should output 10
cout<<st_t[1].m<<endl; // this should output 20
return 0;
}
Is it possible to define a struct array in a function? If it is, then how to do this?
Thanks in advance.
PS:
Sorry my English is not good. I am making a Tetris game, it have a Shape class, I declared a shape struct array in Shape.h, then I assign to the struct array in Shape constructor function in Shape.cpp. Is it right? or how to assign to the struct array so I can use it in another function?
You can initialize an array in the place where it's defined. I.e. either move the definition into the function, or move the initialization out of the function:
struct st
{
int m;
}
st_t[2] = {{10},{20}};
Instead of the direct assignment of values, you can initialize a temporary variable and copy this variable to your global variable:
Delete:
...
st_t[2] = {
{10},{20}
};
...
and add:
...
st tmp[2] = { {10}, {20} };
memcpy(st_t, tmp, sizeof st_t);
...
Addendum:
If it doesn't work for you, there might be another error in your code. From your example:
#include <iostream>
#include <memory.h>
using namespace std;
int i;
struct st { int m; } st_t[2];
void foo()
{
i = 4;
st tmp[2] = { {10}, {20} };
memcpy(st_t, tmp, sizeof st_t); // use: const_addr instead of &const_addr
}
int main()
{
foo();
cout << i << endl; // will output 4;
cout << st_t[0].m << endl; // this should output 10
cout << st_t[1].m << endl; // this should output 20
return 0;
}
all works fine as expected.
If you want to define an array in the function (as your question title and text implies), then add the type specifier st to the definition:
st st_t[2] =
{
{10},{20}
};
However, this will be a separate array to the global one, and so the output from main() won't match what your comments say should happen. If you actually want to assign to the global array, then:
st_t[0].m = 10;
st_t[1].m = 20;
or, in C++11, you can use similar syntax to your example if you replace the plain array with std::array:
std::array<st, 2> st_t;
void foo() {
// Note the extra braces - std::array is an aggregate containing an array
st_t =
{{
{10},{20}
}};
}
If you only want the variable at function scope then
void foo() {
struct {
int m;
} st_t = { {10}, {20} };
// do something
}
Related
class A{
private : string a[3];
public : A();
void ShowA();
}
A::A(){ string a[3] = {"aa","bb","cc"} }
void A::ShowA(){
for(int x=0;x<=2;x++){
cout<< a[x];
}
}
int main(){
A a;
a.ShowA();
return 0;
}
In this code, I think the output is aabbcc but there is nothing. Just blank is existed.
Could you tell me why it happens and how to fix it.
Cheers guys.
As the comments tell you, you are creating a local variable a inside your constructor, instead of setting the value of the attribute a. You can set the value of a in member initializer list.
The code becomes
#include <iostream>
#include <string>
using namespace std;
class A {
private:
string a[3];
public:
A();
void ShowA();
};
A::A() : a{"aa"s, "bb"s, "cc"s} {}
void A::ShowA() {
for(int x = 0; x <= 2; x++) {
cout << a[x] << std::endl;
}
}
int main() {
A a;
a.ShowA();
return 0;
}
Note: The 's' after the "aa", "bb" and "cc" strings is a string literal. It is not really necessary in this case, since the compiler know you are creating an array of std::string objects.
You are re-defining the string "a" in the constructor, you should simply assign it in the constructor instead of using the "string" type again. If you give the type again it creates a local variable available in the scope of the constructor only.
I have a struct Foo;
typedef struct {
int bar;
char baz;
} Foo;
Suppose I then declare an array of Foo as;
Foo* arr = new Foo[300];
And proceed to initialize every member with a loop. I would like very much to be able to get an array of all members bar;
int* barr_arr = ...
What is the most efficient way to do this? Is there some way to exploit the memory layout such that I need not loop over the entire Foo array?
Since we know the memory layout in advance could we exploit the fact that we know the address of every member if we're clever about alignment?
What is the most efficient way to do this? Is there some way to exploit the memory layout such that I need not loop over the entire Foo array?
I don't think there is away to do that without looping. You can simplify your code by using std::transform but std::transform does loop.
Also, I would recommend using std::vector instead of allocating an array using new.
std::vector<Foo> arr(300);
....
std::vector<int> bArr(arr.size());
std::transform(arr.begin(), arr.end(), bArr.begin(), [] -> (Foo const& f) { return f.bar; });
When you are initializing the first array, you can grab a pointer to the field inside each element and store that in a separate array.
struct Foo
{
int bar;
float baz;
};
const int SIZE = 5;
Foo foos[SIZE];
int *bars[SIZE];
for(int c = 0; c < SIZE; c++) {
foos[c].bar = c;
foos[c].baz = c;
bars[c] = &foos[c].bar; // Grab pointer to field
}
for(int c = 0; c < SIZE; c++) {
std::cout << "Bar Value: " << *bars[c] << std::endl;
}
If Foos typically exist in arrays, and corresponding arrays of bars and bazs often need to be accessed, I would suggest redesigning your data structures to better suit your problem. Obviously, we're not reading the code that inspired this question, but given the information provided, I might suggest something like:
struct FooArray {
int* bars;
char* bazes;
size_t n_elements;
};
This removes the need to allocate a new buffer for the bar array, which, depending on how many Foos are being processed, might entail significant memory savings.
I would also note that, if you're not working at a low level and don't actually need an int* but can do with a std::vector<int>, then #R Sahu's answer is likely a more appropriate solution.
The goal drives the design.
If your main use is to pass all bar members in a row, same for baz members, then create separate containers:
std::vector<int> bar;
std::vector<char> baz;
Then passing bar as an array is straightforward: just use bar.data().
If you add a constructor to your Foo that takes the size of array, you could have only one object of Foo. You can then make it that you can access either the whole vector data or individual elements with subscript:
#include <iostream>
#include <vector>
#include <memory>
struct Foo
{
std::vector<int> bars;
std::vector<char> bazs;
std::size_t size;
Foo(size_t size, int bar = 0, char baz = 0) :
bars(size, bar), bazs(size, baz), size{size}
{
}
auto operator[](size_t n)
{
// if (n >= size) ...
struct
{
int &bar;
char &baz;
} temp{ bars[n], bazs[n] };
return temp;
}
};
int main()
{
Foo arr(30, 100, 'a'); // 30 items
std::cout << arr[29].bar << std::endl;
std::cout << arr[29].baz << std::endl;
std::cout << arr.bars[29] << std::endl;
std::cout << arr.bazs[29] << std::endl;
std::unique_ptr<Foo> arr2 = std::make_unique<Foo>(25, 10, 'b'); // 25 items
std::cout << arr2->operator[](15).bar << std::endl;
std::cout << arr2->operator[](15).baz << std::endl;
arr2->bars[15] = 11;
std::cout << arr2->bars[15] << std::endl;
arr2->bazs[15] = 'c';
std::cout << arr2->bazs[15] << std::endl;
return 0;
}
Demo: https://ideone.com/TiVwOT
100
a
100
a
10
b
11
c
I really want to do the following:
(sorry about syntax, I have no idea how this is done)
struct Data {
int var = 5;
} data;
struct Data2 {
var;
} data2;
data2.var = data;
cout << data2.var.var; //prints 5
Basically I want to have a dynamic struct variable in a struct that can be given any struct as value and access it through the mains struct.
Please be nice. I really don't know how to explain it better and I really want to do this and been reading a lot yet haven't found any methods to do this.
Ps.
I DON'T want to do the following:
struct Data {
int var = 0;
} data;
struct Data2 {
data;
} data2;
I want it to be dynamic, that is, that I can change it any time during the program. Thank you.
Conceptually, you may (?) be asking about references:
#include <iostream>
int main() {
int x = 10;
int & xref = x;
std::cout << xref << "\n";
x = 20;
std::cout << xref << "\n";
}
That will print:
10
20
Underlying a reference is essentially a pointer, but it is one which can never be null...and notationally you don't have to "dereference" it. Were you using pointers, the above would look like:
#include <iostream>
int main() {
int x = 10;
int * xptr = &x;
std::cout << *xptr << "\n";
x = 20;
std::cout << *xptr << "\n";
}
Here they are applied to your example with minimal changes:
#include <iostream>
struct Data {
int var;
};
struct Data2 {
Data & var;
};
int main()
{
Data data = {5};
Data2 data2 {data};
std::cout << data2.var.var << "\n";
data.var = 10;
std::cout << data2.var.var << "\n";
return 0;
}
Odds are "this isn't what you actually want" (you shouldn't usually be exposing member variables, much less member variables that are references to other variables). And they shouldn't be all named var. Etc.
Still, references are an integral part of the language and worth learning about.
(Note: for brevity, you may omit the return 0;...only from main. That's assumed, and legal in the standard; and you may omit its arguments. But you must return an int.)
You can use void pointer like this:
#include <iostream>
using namespace std;
struct Data
{
int var;
}data;
struct Data2
{
void *var;
}data2;
int main()
{
data.var = 5;
data2.var = &data;
cout<<((Data *)data2.var)->var<<endl;
return 0;
}
But it is not safe because somtimes you can't make sure that other struct has member called var which may cause unexpected result.
Basically I want to have a dynamic struct variable in a struct that
can be given any struct as value and access it through the mains
struct.
You can emulate the effect of dynamic typing by using polymorphism. The following is a test example for your case.
#include <iostream>
using namespace std;
struct BaseDataStruct
{
virtual int get_data() = 0;
};
struct Data : BaseDataStruct
{
int var = 5;
virtual int get_data() { return var;}
} data;
struct Data2 {
BaseDataStruct* var;
} data2;
int main()
{
data2.var = &data;
cout<<data2.var->get_data();
return 0;
}
By using BaseDataStruct as an interface base class for all the structs which Data2::var is expected to point to you can achieve the "dynamic typing" behavior you are trying to get.
Note: I changed the Data2::var a to pointer to avoid object slicing. You will need to jump through many hoops to avoid that if you want to have it by value.
TL/DR: C++ is statically typed, so what you want to do is against the spirit of thr language. However, if you really have to you can use void* in C and boost::any in C++
Now a bit more about void* (to know more about boost::any refer to its documentation).
void* is a pointer that holds a raw address in memory. This value beyond this address could be everything: float, int or your struct. Here is the usage example.
struct Data {
int var = 5;
};
struct Data2 {
void* var;
};
int main() {
Data data;
Data2 data2;
data2.var = (void*)(&data);
cout << ((struct Data*)data2.var)->var << endl;
}
If the concept of pointers is new for you you can read about it here. Void pointers are explained there as well.
I have this struct:
struct noduri {
int nod[100];
};
and this function:
int clearMatrix(int var)
{
cout << all[1].nod[30];
}
int main()
{
noduri all[100];
cout << all[1].nod[30];
return 0;
}
and I want the struct to be assigned to all 100 elements of array all[], when I do cout << all[1].nod[30]; everything works fine, no errors, it outputs 0. When I call clearMatrix(1) I get this error : error: request for member nod in all[1], which is of non-class type int, what am I doing wrong ?!
The array variable all is local to the main function, so you cannot reference it in clearMatrix unless you pass a pointer to it into the function:
int clearMatrix(int var, noduri *all)
{
cout<<all[1].nod[30];
}
int main()
{
noduri all[100];
clearMatrix(5, all);
return 0;
}
you are reffering in the function that array which is not in its scope, you need to do it as
int clearMatrix(int var,noduri *all)
{
cout<<all[1].nod[30]; // as here you have the base address of the array of type noduri you can refer it.
}
int main()
{
noduri all[100];
clearMatrix(5, all);
return 0;
}
You are using raw arrays. That's not a good idea. Use std::vector if the size if not known at compile time, consider std::array if it is known at compile time and dynamic resizing would cause measurable performance problems.
One of the problems with raw arrays in C++ is that it's not at all(!) as easy to pass them to a function like, say, an int or a double. std::vector and std::array, in contrast, are as easy to pass to a function like any other normal type.
Here's a complete example:
#include <array>
#include <iostream>
struct noduri {
std::array<int, 100> nod;
};
void clearMatrix(std::array<noduri, 100> const &array) {
std::cout << array[1].nod[30];
}
int main() {
std::array<noduri, 100> all;
std::cout << all[1].nod[30];
}
Note that std::array is only available if your compiler supports C++11. For an older compiler, use boost::array or just do it with a std::vector.
The code you showed will not be compiled and has no any sense. If I have understood correctly you want to assign each element of the array by some value in function clearMatrix. If so then the code will look the following way
#include <iostream>
struct noduri
{
int nod[100];
};
int clearMatrix( noduri *matrix, int size, int var )
{
for ( int i = 0; i < size; i++ )
{
for ( int &n : matrix[i].nod ) n = var;
}
}
int main()
{
const int N = 100;
noduri all[N] = {};
std::cout << all[1].nod[30] << std::endl;
clearMatrix( all, N, 10 );
std::cout << all[1].nod[30] << std::endl;
return 0;
}
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.