How to make a struct of structs in C++ - c++

Can a struct contain other structs?
I would like to make a struct that holds an array of four other structs. Is this possible? What would the code look like?

Yes, you can. For example, this struct S2 contains an array of four S1 objects:
struct S1 { int a; };
struct S2
{
S1 the_array[4];
};

Sure, why not.
struct foo {
struct {
int a;
char *b;
} bar[4];
} baz;
baz.bar[1].a = 5;

Yes, structs can contain other structs. For example:
struct sample {
int i;
char c;
};
struct b {
struct sample first;
struct sample second;
};

Related

How to access a structure member without knowing the name?

How can we access a structure's member without knowing the name of it?
For example : This is my struct.
struct A
{
int a;
char b;
int c;
}
Now I want to access char member of the struct A without using it's name.
I have only a pointer to that structure.
Example : struct A *temp;
Now I need to access with 'temp'.
I know the question is simillar to this How would you access a C structure's members without knowing the name?,
but it doesn't clarified my doubt.
From the comments, I understand you have the following function
struct A;
void foo( struct A * temp )
{
// access temp->b here
}
If you can include the file that has struct A's definition, do so
#include "A.h"
void foo( struct A * temp )
{
do_something_with_b(temp->b);
}
If you can't include the file, do what Luc Forget suggested in his answer:
Declare a struct B with identical structure, and cast temp to struct B. Because struct B have the same memory layout as struct A, accessing ((struct B*)temp)->e is identical to accessing A->b.
If you what are the structure fields, I think the simplest way of accessing the fields is to declare another structure Struct B with the same fields and casting your struct A* to struct B and then accessing the fields in a "traditional" way.
Here is a simple example of what I mean :
#include <stdlib.h>
#include <stdio.h>
struct A {
int a;
char b;
int c;
};
struct B {
int d;
char e;
int f;
};
void printStruct(void* struct_ptr)
{
struct B *tmp = struct_ptr;
fprintf(stdout, "a:%d b:%c c:%d\n", tmp->d, tmp->e, tmp->f);
}
int main(int argc, char** argv)
{
struct A test = { 42, 'A', 24 };
printStruct(&test);
}
Here printStruct "doesn't know" the field names of Struct A but can access them
If You know the types and order of members (as well as packing) then You can create another struct and cast a pointer, like so:
struct AMirror {
int a;
char b;
int c;
};
void function_to_use_struct(AMirror *ptr);
...
A *s;
...
function_to_use_struct((AMirror*)s);
The below code should work
void *b=temp;
int *c = (int *) b;
cout<<"Value1: "<<*c <<endl;
char *cc =(char *) (b+4);
cout<<"Char1: "<<*cc<<endl;
c =(int *) (b+6);
cout<<"Value2: "<<*c<<endl;
I guess one way is to cast and increment the char* , but in this case you must know the types and order of declarations of your members.

typedef usage in struct definition

I have problem with this code,this is a header file(stack.h) from a maze program. i was studying Stack structure, and in my documents, i couldn't understand these type of structures, can anyone explain to me why we are using typedef and how the 12th and 21st line works??
#ifndef STACK_H
#define STACK_H
#define STACKSIZE 50
typedef struct d {
int x;
int y;
int right; int left;
int down;
int up;
int camefrom;
} StackDataType, position; /// LINE 12
struct STACK{
StackDataType element[STACKSIZE]; int top;
void create();
void close();
bool push(StackDataType); StackDataType pop();
bool isempty();
};
typedef struct STACK Stack; /// LINE 21
#endif
I think you do not need to typedef a struct again in C++, it again defines a struct, which is unnecessary. You can just define:
struct d{
};
In my (considerable) experience, this almost always denotes a C programmer who has fumbled their way into C++. If these are notes from your classes, it doesn't bode well.
In the earliest "C", if you declared a struct
struct StructName {
int a;
int b;
};
This didn't declare a type name, it only declared a struct name, so to make an instance of StructName you would have to write:
struct StructName myStruct;
If you wanted to be able to omit the "StructName" part you would need to use a typedef:
struct StructName { int a, b; };
typedef struct StructName StructName;
Or you could combine these into one, somewhat confusing, statement:
typedef struct StructName { int a, b; } StructName;
I say confusing because if the struct definition is many lines long, it could be confused for a second C syntax which lets you declare an instance of a Struct after defining the type:
struct StructName { int a, b; } StructName;
// aka
struct StructName { int a, b; };
struct StructName StructName; // local variable, StructName of type struct StructName
// declare a VARIABLE called StructName which is of type anonymous-struct.
struct { int a, b; } StructName;
One problem with this is that you can't use the typedef'd name in the structure declaration:
// Won't compile because 'List' isn't declared until the end.
typedef struct list_structure { List* next; int a; } List;
// Won't compile because you have to remember to say 'struct List'
typedef struct List { List* next; int a; } List;
// Compiles
typedef struct list_structure { struct list_structure* next; int a; } List;
This confused a lot of C programmers. Enough so that many C programmers will tell you that the definition of a struct is
typedef struct tag_name { /* struct details */ } structname;
//e.g.
typedef struct tagStructName { int a, b; } StructName;
C++ inherited all of this, but also went ahead and made the typedef implied for you:
// doesn't compile as C, will compile as C++
struct List {
List* next;
int a;
};
To see it not compiling as C: http://ideone.com/3r9TRy
In C++, declaring something as a class is exactly the same as declaring it a struct, with one change:
class List {
List* next;
public:
int a;
};
Is EXACTLY as though you had written:
struct List {
private:
List* next;
public:
int a;
};
There's no other difference between a struct and a class in C++.
I can see two problems: The first is the mysterious symbol  in the definition of the d structure. The second is that you use typedef for that structure too, but have something after the typename StackDataType. The second error you get is probably just because of the first one, it's very common in C and C++ to get errors in unrelated lines because of previous errors.
Besides, in C++ you don't really need typedef for structures, as they are the same as classes so doing e.g. struct StackDataType {...}; will allow you to use StackDataType as a type.
What's going on is that essentially the typedef is being used to create a shorthand way to refer to the given structure.
So in this example, both StackDataType and position are shorthand references to what is formally declared as struct d, and Stack is a shorthand reference to what is formally declared as struct STACK.
Generally speaking, this allows for cleaner code referencing these structures. E.g., instead of having to write:
struct STACK var;
to declare an instance of this structure, you can just use:
Stack var;
You can declare a typedef either at the same point at which you declare the type (as in the first example), or you can declare it later (as in the second).

How to use anonymous struct or class?

So, it's possible to declalre anonymous class or struct but how to I make it useful?
int main() {
class{
int ClassVal;
};
struct{
short StructVal;
};
StructVal = 5; //StructVal is undefined
ClassVal = 5; //ClassVal is undefined too?
return 0;
}
if you put both of them outside of main function they will be inaccessible as well.
I'm asking this only because it's somehow intersting :)
EDIT:
Why union outside of main function (at global scope) must be static declared
for example:
static struct {
int x;
};
int main() {
//...
}
Anonymous classes and structures may be used to directly define a variable:
int main()
{
class
{
int ClassVal;
} classVar;
struct
{
short StructVal;
} structVar;
structVar.StructVal = 5;
classVar.ClassVal = 5;
return 0;
}
The above is not very common like that, but very common when used in unions as described by Simon Richter in his answer.
These are most useful in the form of nested struct and union:
struct typed_data {
enum type t;
union {
int i; // simple value
struct {
union { // any of these need a length as well
char *cp;
unsigned char *ucp;
wchar_t *wcp;
};
unsigned int len;
};
};
};
Now typed_data is declared as a type with the members t, i, cp, ucp, wcp and len, with minimal storage requirements for its intended use.

How to use a struct inside another struct?

I want to use a nested structure, but I don't know how to enter data in it. For example:
struct A {
int data;
struct B;
};
struct B {
int number;
};
So in main() when I come to use it:
int main() {
A stage;
stage.B.number;
}
Is that right? If not how do I use it?
Each member variable of a struct generally has a name and a type. In your code, the first member of A has type int and name data. The second member only has a type. You need to give it a name. Let's say b:
struct A {
int data;
B b;
};
To do that, the compiler needs to already know what B is, so declare that struct before you declare A.
To access a nested member, refer to each member along the path by name, separated by .:
A stage;
stage.b.number = 5;
struct A {
struct B {
int number;
};
B b;
int data;
};
int main() {
A a;
a.b.number;
a.data;
}
struct B { // <-- declare before
int number;
};
struct A {
int data;
B b; // <--- declare data member of `B`
};
Now you can use it as,
stage.b.number;
The struct B within A must have a name of some sort so you can reference it:
struct B {
int number;
};
struct A {
int data;
struct B myB;
};
:
struct A myA;
myA.myB.number = 42;
struct A
{
int data;
struct B
{
int number;
}b;
};
int main()
{
A stage = { 42, {100} };
assert(stage.data == 42);
assert(stage.b.number == 100);
}
struct TestStruct {
short Var1;
float Var2;
char Var3;
struct TestStruct2 {
char myType;
CString myTitle;
TestStruct2(char b1,CString b2):myType(b1), myTitle(b2){}
};
std::vector<TestStruct2> testStruct2;
TestStruct(short a1,float a2,char a3): Var1(a1), Var2(a2), Var3(a3) {
testStruct2.push_back(TestStruct2(0,"Test Title"));
testStruct2.push_back(TestStruct2(4,"Test2 Title"));
}
};
std::vector<TestStruct> testStruct;
//push smthng to vec later and call
testStruct.push_back(TestStruct(10,55.5,100));
TRACE("myTest:%s\n",testStruct[0].testStruct2[1].myTitle);
I have somewhat like the following code running for a while live now and it works.
// define a timer
struct lightTimer {
unsigned long time; // time in seconds since midnight so range is 0-86400
byte percentage; // in percentage so range is 0-100
};
// define a list of timers
struct lightTable {
lightTimer timer[50];
int otherVar;
};
// and make 5 instances
struct lightTable channel[5]; //all channels are now memory allocated
#zx485: EDIT: Edited/cleaned the code. Excuse for the raw dump.
Explanation:
Define a lightTimer. Basically a struct that contains 2 vars.
struct lightTimer {
Define a lightTable. First element is a lightTimer.
struct lightTable {
Make an actual (named) instance:
struct lightTable channel[5];
We now have 5 channels with 50 timers.
Access like:
channel[5].timer[10].time = 86400;
channel[5].timer[10].percentage = 50;
channel[2].otherVar = 50000;

Is there anyway to create a non-type template parameter for a class but not declare using <>?

My original code looks like this:
class a{
...
char buff[10];
}
and im attempting to make this change to the code:
template <int N = 10>
class a{
...
char buff[N];
}
Is there any thing I can do to keep my existing code creating instances of class a like this:
a test;
instead of making the change to:
a<> test;
to get the default parameter?
You can't instantiate a template without angle-brackets, and you can't give a type the same name as a template, so you can't do exactly what you want.
You could give the template a different name, and typedef a to the default-sized one.
Well, don't make the class a template is the obvious answer - use something like:
class a {
public:
a( int n = 10 ) : buff(n) {}
private:
std::vector <char> buff;
};
Not in really good ways. You can typedef X to be X<> in a different namespace:
namespace lib {
template<int N=10>
struct X
{
int t[N];
};
}
typedef lib::X<> X;
int main()
{
X a;
lib::X<20> b;
}
-- or --
template<int N=10>
struct X
{
int t[N];
};
int main()
{
typedef X<> X; // functions have their own namespace!
X a;
::X<20> b;
}
Nope. The empty angle brackets are required.