Routine pointer to struct with struct as parameter - c++

I have a chicken and the egg problem. I want to pass a data struct to a routine which contains a pointer to a routine who needs the struct.
I made a very simple example.
I need to use the CalcDataStruct before it's defined, if I add it after the struct, the FuntctionPrototype is not defined.
The problem i run against is only in the first 2 lines, the rest may contain a few syntax errors because I have not checked this inside the compiler.
typedef void(*FunctionPrototype)(CalcDataStruct *Ptr);
struct CalcDataStruct
{
int A, B, C, D;
int Values;
char SignA, Sign B;
int Result;
FunctionPrototype Routine;
}
struct ScanStruct
{
char Sign;
int Values;
FunctionPrototype Routine;
};
const ScanStruct ExampleList[] =
{
{ '+', 2, AddTwo },
{ '+', 3, AddThree }
};
void AddTwo(CalcDataStruct *Ptr)
{
// use the data and if needed put it back
}
void AddThree(CalcDataStruct *Ptr)
{
// use the data and if needed put it back
}
void GetFunction(CalcDataStuct *Ptr, ScanStruct *List)
{
// Very simple return based on nothing
Ptr->Routine = *List[(1)].Routine;
}
void main()
{
CalcDataStruct A;
// struct is filled
// Fill in the routine pointer based on data
GetFunction(A, ExampleList)
// Execute the routine fetched with all the data
A->Routine(A)
}

You need to add a forward declaration (see below).
struct CalcDataStruct; will just declare that struct CalcDataStruct exists, so the typedef void(*FunctionPrototype)(CalcDataStruct *Ptr); declaration will succeed because now the compiler knows that struct CalcDataStruct exists but without knowing the details of the struct, which doesn't matter because all the FunctionPrototype declaration needs is to know that the parameter is a pointer to struct CalcDataStruct.
struct CalcDataStruct; // <<< add this
typedef void(*FunctionPrototype)(CalcDataStruct *Ptr);
struct CalcDataStruct
{
int A, B, C, D;
int Values;
char SignA, Sign B;
int Result;
FunctionPrototype Routine;
}

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).

C++. 1Class with changing parameters

I've got a class with 3 private variables and one public method, that has 2 char parameter variables.
class InitLine
{
private:
char *a;
char b, c;
public:
InitLine(char *inita, char initc);
Init(char *a, char c);
};
Now the definition of the method is simple:
Initline::Init(char *a, char c)
{
for (b=0; b<c; b++)
*(a+c)=0;
}
Now my question is: If I wish to repeat the same actions with different parametertypes (*a and c, or one of them becomes an integer e.g.), is it necessary to create a new class, or can I use the existing one, doing some 'typecasting' or some other trick I don't know yet?
Thanks and regards
Uwe
Use templates, make the Init function a template of your arguments type.
template <typename T>
Init(char*a , T c){}
for instance
You have many places in your code, which should be fixed prior to any further operations.
Naming convention is terrible. What is a, b, c?
You use b as a loop indexer, while a local variable should be used there instead.
You don't show us, what is a. Where is it allocated? What is the size of memory pointed to by a?
I guess, that your code should look like the following:
class InitLine
{
private:
char * data;
int count;
public:
InitLine(char * newData, int newCount)
{
// Possible error checking?
data = newData;
count = newCount;
}
// No parameters needed here, I guess
void Init()
{
for (int i = 0; i < count; i++)
data[i] = 0;
}
};
As for your question, I'm not really sure, what you are trying to achieve and what do you want to know. If you want to write a generic class holding any type of arrays, you have to use templates:
template <typename T>
class InitLine
{
private:
T * data;
int count;
public:
InitLine(T * newData, int newCount)
{
// Possible error checking?
data = newData;
count = newCount;
}
// No parameters needed here, I guess
void Init()
{
for (int i = 0; i < count; i++)
data[i] = 0;
}
};
You have to use this class in the following way:
InitLine<char> line(myData, myDataSize);
// where myData is a char * and myDataSize is an int
If you want to write a few methods differing by their parameters, this technique is called method overloading and is available in C++:
void Init(char * a, int b) { /* sth */ }
void Init(int * a, int b) { /* sth */ }
Note, that compiler must be able to clearly distinguish, which method should be called. Eg.
void Test(int a) { }
void Test(char a) { }
Test(0); // Ambiguity: which method should be called?
These are only things coming to my mind, while reading your question. If it is not what you are asking for, consider editing the question to be more specific.
If you just want to have the whole class with different types (not just the Init), e.g. also have int *a; int b,c; then template classes are the other trick you don't know yet.
template <typename ANYTYPE> class InitLine
{
private:
ANYTYPE *a;
ANYTYPE b, c;
public:
void InitLine(ANYTYPE *inita, ANYTYPE initc);
void Init(ANYTYPE *a, ANYTYPE c);
};
template <typename ANYTYPE> void Initline<ANYTYPE>::Init(ANYTYPE *a, ANYTYPE c)
{
for (int b=0; b<c; b++)
*(a+c)=0;
}
... main()
{
Initline<int> iline; // initline class based on type int (ANYTYPE -> int)
int line[20];
Initline<char> cline; // initline class based on type char (ANYTYPE -> char)
char somechars[30];
iline.Init(line, 20);
cline.Init(somechars, 30);

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;

structures and pointers

I'm not sure what I'm doing...
Let say I have a structure
struct Inner{
exampleType a;
int b;
}
struct Outer{
int current;
int total;
Inner records[MAXNUMBER];
}
struct Outer2{
Outer outer;
}
And I have the following functions:
void try3( Outer2& outer, type var, type2 var2 ){
}
void try2( Outer2* outer ){
try3(*outer, var, var2);
}
Inside main:
int myMain( int argc, char *argv[] ){
Outer2 outer2;
try2 (&outer2);
}
Here's the question. Can I increment the value of current by sticking the following line in try3:
++outer.outer.current;
errr, no, try3 has no knowledge of a thing caller outer2.
you can go outer.outer.current++; in try3
Sure you can, why not? Here is a working example for you:
typedef short exampleType;
struct Inner
{
exampleType a;
int b;
};
struct Outer
{
enum { MAXNUMBER = 2 };
int current;
int total;
Inner records[MAXNUMBER];
};
struct Outer2
{
Outer outer;
};
typedef int type;
typedef int type2;
void try3 (Outer2& outer, type var, type2 var2)
{
++outer.outer.current;
}
void try2 (Outer2* outer)
{
int var = 1, var2 = 2;
++outer->outer.current;
try3(*outer, var, var2);
}
int main ()
{
Outer2 outer2;
outer2.outer.current = 1986;
try2 (&outer2);
}
From try3, you would need to use ++outer.outer.current since outer is the name of the variable at the point. To answer the actual question though, look at the two functions. try2 takes a pointer to an Outer2, so no copy is made. try2 passes this to try3 which take a reference to an Outer2, so again no copy is made. This means that yes, ++outer.outer.current will in fact affect the original outer2 declared in myMain.
Edit (per Brian's comment)
However, outer.outer.current is never initialized, unless that's not your true myMain, so the final value of current is undefined since the value was never defined before the increment.