Code
typedef struct
{
int *x;int *y;
}point;
void move(point *p)
{
(*p).x=(*p).x+1;
(*p).y=(*p).y+1;
}
int main()
{
point p;
p.x = 10;
p.y = 5;
printf("%d, %d\n", p.x, p.y);
move(&p);
printf("%d, %d\n", p.x, p.y);
return 0;
}
Detail
I want to output 10,5 and 11,6 but it shows me 10,5 and 15,9. What's wrong with my code?
You have very little idea of what a pointer is. int* means it will contain the address of the int variable. p.x = 10 is saying that, assign 10 to this pointer variable. Then you are printing that pointer with wrong format specifier.
Then you have incremented those pointer. Accessing this would be disaster. And it's not strange that +1 on pointer will move it by sizeof(int). So the value you saw is 14 and 9.
typedef struct {int x;int y;}point;
This is what you have wanted for sure. Also other thing that is already mentioned is (*p).x = p->x. That's it.
You are wrong when you said output is 15,9 it will be 14,9. sizeof(int) = 4 in your system. To provide some more information pointers should be printed using %p format specifier like this.
int *p;
...
printf("%p\n",(void*)p);
I implemented this code and i got the output like this 10,5 and 14,9
there is 2 alternative ways to get the output like this 10,5 and 11,6
typedef struct
{
int *x;int *y;
}point;
replace the code with this :
`typedef struct
{
int x;int y;
}point;`
or
typedef struct
{
char *x; char *y;
}point;
Related
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 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 !
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.
I'm new to C and I have a function that calculates a few variables. But for now let's simplify things. What I want is to have a function that "returns" multiple variables. Though as I understand it, you can only return one variable in C. So I was told you can pass the address of a variable and do it that way. This is how far I got and I was wondering I could have a hand. I'm getting a fair bit of errors regarding C90 forbidden stuff etc. I'm almost positive it's my syntax.
Say this is my main function:
void func(int*, int*);
int main()
{
int x, y;
func(&x, &y);
printf("Value of x is: %d\n", x);
printf("Value of y is: %d\n", y);
return 0;
}
void func(int* x, int* y)
{
x = 5;
y = 5;
}
This is essentially the structure that I'm working with. Could anyone give me a hand here?
You should use *variable to refer to what a pointer points to:
*x = 5;
*y = 5;
What you are currently doing is to set the pointer to address 5. You may get away with crappy old compilers, but a good compiler will detect a type mismatch in assigning an int to an int* variable and will not let you do it without an explicit cast.
void function(int *x, int* y) {
*x = 5;
*y = 5;
}
would change the values of the parameters.
In addition to the changes that the other posters have suggested for your function body, change your prototype to void func(int *,int *), and change your function definition (beneath main) to reflect void as well. When you don't specify a return type, the compiler thinks you are trying to imply an int return.
You can't forward declare func(int,int) when in reality it is func(int*, int*). Moreover, what should the return type of func be? Since it doesn't use return, I'd suggest using void func(int*, int*).
You can return a single variable of a struct type.
#include <stdio.h>
#include <string.h>
struct Multi {
int anint;
double adouble;
char astring[200];
};
struct Multi fxfoo(int parm) {
struct Multi retval = {0};
if (parm != 0) {
retval.anint = parm;
retval.adouble = parm;
retval.astring[0] = parm;
}
return retval;
}
int main(void) {
struct Multi xx;
if (fxfoo(0).adouble <= 0) printf("ok\n");
xx = fxfoo(42);
if (strcmp(xx.astring, "\x2a") == 0) printf("ok\n");
return 0;
}