I have the following code:
typedef struct {
double x, y;
} point_t ;
typedef struct {
point_t a, b, c;
} triangle_t;
int read_point(point_t * const point) {
int status = scanf(" (&lf,&lf)", &point_t.x, &point_t.y);
return(status);
}
I'm trying to read an x and y coordinate that the user enters for the vertexes of a triangle (Points a, b and c.) However, I'm getting a weird error underlining both instances of "point_t" in the scanf function.
Type name is not allowed.
What's going on?
Change it to:
int status = scanf(" (%lf,%lf)", &(point->x), &(point->y));
Remember to use the variable name point, not the type name point_t. It also important to note that you must use the operator -> on pointer types (it is equivalent to dereferencing it and then using the member operator [p->x == (*p).x]).
try this code
typedef struct {
double x;
double y;
} point_t ;
typedef struct {
point_t a;
point_t b
point_t c;
} triangle_t;
int read_point(point_t * point) {
int status = scanf(" (&lf,&lf)", point->x, point->y);
return(status);
}
I think in struct, you should declare each field with it's type; multiple declaration as int x,y doesn't work.
Secondly, you are passing a pointer so to access you should use the name of your argument ( "point" is this case) this way point->field or (*point).field and not &point !
Related
I have created a structure called Register, with around 8 fields within it. I now want to create a structure called Instrument, which should have a variable amount of of fields, 6 which are the same for every instrument, plus a certain amount of fields depending on how many registers are attributed to it. How can I create this?
For clarity here is what I would like to create (although may not be accurate).
typedef struct {
int x;
int y;
int z;
} Register;
typedef struct {
int x;
int y;
int z;
Register Reg1;
Register Reg2;
...
} Instrument;
You can make use of flexible array members to achieve the same.
Something like
typedef struct {
int x;
int y;
int z;
Register Reg1;
Register Reg2; //upto this is fixed....
Register Reg[];
} Instrument;
and then, you can allocate memory as needed to someVar.Reg later.
For an example, quoting C11, chapter ยง6.7.2.1/20
EXAMPLE 2 After the declaration:
struct s { int n; double d[]; };
the structure struct s has a flexible array member d. A typical way to use this is:
int m = /* some value */;
struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));
and assuming that the call to malloc succeeds, the object pointed to by p behaves, for most purposes, as if
p had been declared as:
struct { int n; double d[m]; } *p;
You can use pointers
typedef struct
{
int x;
int y;
int z;
Register *reg;
} Instrument;
use it into code
Instrument a.reg = malloc(sizeof(Register)*NUM_OF_REGISTERS);
if (a.reg != NULL)
{
// your STUFF
free(a.Reg);
}
To explain more, I have two structures-'first' and 'second' having common variables 'jack' and 'jill'. I want to print jack via a pointer based on if-else condition.
I understand at the time of printing I have to typecast the void pointer. But whether the pointer points to struct a or b is decided on run time.
It is a basic C code. How to overcome this?
Code
#include <stdio.h>
int main(void)
{
typedef struct one
{
int jack;
float jill;
}a;
typedef struct two
{
int jack;
float jill;
char something;
int something1;
}b;
a first;
b second;
void *z;
if(1)
{
a* z;
z = &first;
printf("First one");
}
else
{
b* z;
z = &second;
printf("Second one");
}
printf("%d\n", z->jack);
return 0;
}
Error
prog.c:36:17: warning: dereferencing 'void *' pointer printf("%d\n", z->jack); prog.c:36:17: error: request for member 'jack' in something not a structure or union
You get a compiler warning since the compiler does not understand z->jack since z is a void * (note that the declarations a* z and b* z are not valid outside the scope of the if and else block).
To overcome this you can use a function printJack as shown in the following listing:
#include <stdio.h>
typedef struct one
{
int jack;
float jill;
}a;
typedef struct two
{
int jack;
float jill;
char something;
int something1;
}b;
void printJack(void *pStruct, int type)
{
switch (type)
{
case 1:
printf("jack: %d\n", ((a *)pStruct)->jack);
break;
default:
printf("jack: %d\n", ((b *)pStruct)->jack);
break;
}
}
/*
** main
*/
int main(void)
{
a first;
b second;
void *z;
first.jack = 5;
second.jack = 4892;
printJack(&first, 1);
printJack(&second, 0);
z = &first;
printJack(z, 1);
return (0);
}
I've written code like this often and experienced a lot of trouble with it. Not at the time of implementing, since you are knowing what you are typing at that moment but let's say a few years later if you need to extend your code. You will miss a few places where you cast from void * to a * or b * and you'll spend a lot of time debugging what's going on...
Now I'm writing things like this in the following way:
#include <stdio.h>
typedef struct header
{
int jack;
float jill;
} h;
typedef struct one
{
struct header header;
/* what ever you like */
}a;
typedef struct two
{
struct header header;
char something;
int something1;
/* and even more... */
}b;
void printJack(void *pStruct)
{
printf("jack: %d\n", ((struct header *)pStruct)->jack);
}
/*
** main
*/
int main(void)
{
a first;
b second;
void *z;
first.header.jack = 5;
second.header.jack = 4892;
printJack(&first);
printJack(&second);
v = &first;
printJack(v);
return (0);
}
As you've noticed I have declared a new struct header which covers the the common parts of struct one and struct two. Instead of casting the void * to either a * or b * a "common" cast to struct header * (or h *) is done.
By doing so you can easily extend the "common attribtues" of the structs or you can implement further structs using this header and function printJack still will work. Additionally there is no need for attribute type anymore making is easier to call printJack. You can even change the type of jack without needing to change it in various places within your code.
But remember that struct header needs to be the first element of the structs you use this mechanism. Otherwise you will end up with a few surprises since you are using memory which does not contain the data of the struct header...
I try to write a function, that finds void pointers in a data structure. The function has to cast the void* to any kind of struct.
Let's say I write a struct, which I store in my data sturcture in form of a void pointer. Then I calls the function, which prints information of all stored data elements.
To do that the function has to know to which type it should cast.
So my question is: Is it possible to give the function the informations it needs in form of a parameter somehow?
example code:
typedef struct{
int a, b
} teststruct;
void DSOut(datastructure* ds, datatypeinfo dt){
//...
//search for data in ds
//...
//if data is found cast it to the type defined in dt
//and print out the a and b fields
}
int main(){
datastructure* ds = DSCreate(4, 3); //can hold any type of data,
//but should hold just one at a time
//4 and 3 are just example parameters
teststruct ts;
ts.a = 4;
ts.b = 10;
teststruct ts2;
ts2.a = 6;
ts2.b = 12;
//Add the teststructs to the data-structure
DSAdd(2, 2, ts); //the numbers are just for example
DSAdd(4, 1, ts2);
datatypeinfo dt = teststruct; //stores the type teststruct for DSOut
DSOut(ds, dt); //function, that prints information of all added teststructs
return 0;
}
in this example DSOut(x,y) should print the following:
- on position 2, 2 is an element which holds following data: 4, 10.
- on position 4, 1 is an element which holds following data: 6, 12.
Do you think this is possible ?
Types cannot be passed as parameters in C, so the short answer to your question is "no, it cannot be done", at least not in the general case. You could pass something that would allow you to identify one of a limited set of types, and then hard-code how to handle each of those types (I'm thinking of a big switch statement). Since you don't specify what datatypeinfo looks like, it isn't clear how general you expect it to be.
I can think of adding a type identifier field to your struct and check it's value to decide how to print it, and initialize the structs with functions to take care of the type field
enum Types {
Point3D,
Point2D
};
struct Base {
enum Types type;
};
struct Point3D {
enum Types type;
int x;
int y;
int z;
};
struct Point2D {
enum Types type;
int u;
int v;
};
void print(void *data)
{
switch (((struct Base *)data)->type)
{
case Point2D:
{
struct Point2D *point;
point = (struct Point2D *)data;
printf("2D: %d, %d\n", point->u, point->v);
}
break;
case Point3D:
{
struct Point3D *point;
point = (struct Point3D *)data;
printf("3D: %d, %d, %d\n", point->x, point->y, point->z);
}
break;
}
}
void initialized2dPoint(struct Point2D *const point, int u, int v)
{
if (point == NULL)
return;
point->type = Point2D;
point->u = u;
point->v = v;
}
void initialized3dPoint(struct Point3D *const point, int x, int y, int z)
{
if (point == NULL)
return;
point->type = Point3D;
point->x = x;
point->y = y;
point->z = z;
}
int main(void)
{
struct Point2D point2d;
struct Point3D point3d;
initialized2dPoint(&point2d, 1, 2);
initialized3dPoint(&point3d, 3, 4, 5);
print(&point2d);
print(&point3d);
return 0;
}
I met a very strange problem.
I defined a struct and passed it as a const pointer into a function. The code is like bellow.
typedef struct a{
char str1[256];
...
int x;
}a_t;
int f(..., const a_t *a){...}
a_t a;
...
a.x = 1;
f(..., &a);
...
The problem is once it enters the f(), I will print out the variable a->x, which is always 0!??
But if I move the struct member x to the top of the struct (before other members), it will be 1, which is correct.
Are there any tricks or traps for using struct pointer as the parameter?
[EDIT1] The printf is called in the 1st line of function f()
Cannot comment so I will suggest debugging option. Can you please add print of the struct element x address in the function and before. If it is the same someone is changing it, otherwise we are not looking at the same value.
typedef struct a{
char str1[256];
...
int x;
}a_t;
int f(..., const a_t *a)
{
printf("X value %d, address %p", a->x, &(a->x));
...
}
a_t a;
...
a.x = 1;
printf("X value %d, address %p", a.x, &(a.x));
f(..., &a);
...
Also detail view of the function could help
Given two structure in c:
typedef struct _X_
{
int virtual_a;
int virtual_b;
void *virstual_c;
int a;
int b;
void *c;
/* More fields to follow */
}X;
typedef struct _Y_
{
int a;
int b;
void *c;
/* Same fields as in X structure */
}Y;
Q : Is it safe to say that ?
void foo_low( Y *y )
{
y->a = 1;
y->b = 2;
}
void foo( X *x )
{
Y *y = (Y *)(&(x->a) )
foo_low( y );
}
Is it standard C ? will it work on all compilers ? Is there any problem with padding ?
No, your function foo won't work, because a is in the wrong place.
Your example is clearly made up and tha's going to reduce the relevance of my answer to the problem you are really trying to solve, but this definition does something like I believe you are asking for:
struct header {
int a;
int b;
void *c;
};
struct shared_fields {
int a;
int b;
void *c;
/* More fields to follow */
};
typedef struct
{
struct header virtuals;
struct shared_fields shared;
} X;
typedef struct
{
struct shared_fields shared;
} Y;
void foo_low(struct shared *ys)
{
ys->a = 1;
ys->b = 2;
}
void foo(X *x)
{
foo_low(&x->shared);
}
However, this does not perform a cast, since one is not needed. If you really intended to set data via one struct and access it via another, this is not allowed in standard C (though there might be an exception for same-struct-with-different labels as described by Hubert).
I suspect that a better solution to the problem you asked about is the use of union which can often be used to do what you may have in mind. But strictly speaking, if you have an object u of union type and you set u.a, accessing the value of u.b before setting u.b has undefined behaviour. Though commonly people do not worry about that.
That should work. But since you need to access the same fields in two distinct ways (y->a and x->a are different), I would use union:
typedef struct _Y_
{
int a;
int b;
void *c;
/* Same fields as in X structure */
}Y;
typedef struct _X_
{
int virtual_a;
int virtual_b;
void *virstual_c;
Y y_fields;
}X;
typedef union {
X x;
Y y;
} Z;
Now x.virtual_a and y.a are in the same memory address.
And you can rewrite your code as follows:
void foo_low( Z *z )
{
z->y.a = 1;
z->y.b = 2;
}
void foo( Z *z )
{
Z *w = z;
w->y = z->x.y_fields;
foo_low( w );
}
The only clumsy part is adding Y inside X.
if both structs have identically structure it is ok. Names of fields inside the struts need not to be the same, but their types must be the same. Each subfield in X must match to a subfield in Y in its type and position. Names of fields can be different.