Basic struct question C - c

for example:
typedef struct {
int num;
int den;
} rational_number;
rational_number a;
What is the difference between using
a.num or a.den
and
a->num or a->den
Thx in advance.

-> is for accessing the members of a pointer to a struct, whereas . is for accessing members of the struct itself. a->num is really just shorthand for (*a).num. Example:
typedef struct {
int num;
int den;
} rational_number;
rational_number a;
r.num = 1;
rational_number *a_ptr = &a;
a_ptr->num = 2; /* a.num is now 2 */

you use a.num, when it is normal variable, and a->num when it is pointer
For ex.
rational_number a;
a.num; // is correct
a->num; // is wrong
rational_number *b;
b.num;// wrong
b->num; //is correct

The difference is that in the first case you access the structure via a stack variable:
rational_number a;
a.num = 1;
a.den = 1;
in the second case via a heap pointer:
rational_number* a = new rational_number();
a->num = 1;
a->den = 1;

If a were declared as a pointer to your structure, a->num would return the value of num.
rational_number *a;
a->num = 5;
int new_a;
new_a = a->num;
You have a is declared as a structure, so you should use a.num to return the value of num.
rational_number a;
a.num = 5;
int new_a;
new_a = a.num;
Both set the value of new_a to 5.
Also, you can get the address of a if it is a structure and use it like a pointer.
rational_number a;
(&a)->num = 5;
int new_a;
new_a = a.num;

Related

C incomplete Type in structs

He folks,
i got a problem and a question.
Hopefully u can help and explain me.
first of all i have 2 stucts:
typedef struct {
double x;
double y;
} A;
typedef struct {
unsigned int count;
A(*stack)[];
}B;
this struct B i declare in main() and passing a Pointer of B to a function this will initializ
main(){
B x;
function rr(&x);
}
void rr(B* test) {
test->stack= malloc((4) * sizeof(A)); //4Elements
for (unsigned int i = 0; i < 4; i++) {
(test->stack+ i)->x= 89;
}
}
on this line
(test->stack+ i)->x= 89;
compiler says incomplete Type
i know why it is incomplete cause in struct B their is no dimension.
but array should initialize in function rr
Maybe u understand what i mean and how to solve my problem.
function rr i am not allowed to change.
Greetings
EDIT 1
Thank you for all answers
mabey i schould clearify my problem
typedef struct {
unsigned int count;
A(*stack)[]; // here i want a pointer to an array of A's
}B;
//over main it is declared
void rr(B*);
main(){
B x;
function rr(&x);
}
// this func is not allowed to change
void rr(B* test) {
test->stack= malloc((4) * sizeof(A)); //4Elements
for (unsigned int i = 0; i < 4; i++) {
(test->stack+ i)->x= 89; // error cause incomplete type but i
//have to use this line
}
}
Hope now it is easier to i understand what i want
This declaration:
A(*stack)[];
Says that stack is a pointer to an array of A of unknown size. That is an incomplete type which means it can't be used directly.
It seems like what you actually want is not a pointer to an array, but a pointer to the first member of a dynamic array of A. So declare the member as a pointer:
A *stack;
In the expression:
(test->stack+ i)->x= 89;
before accessing an array via a pointer to an array you must dereference it.
Try:
(*test->stack)[i].x= 89;
You do not know how to use flexible array members.
Simply:
typedef struct {
double x;
double y;
} A;
typedef struct {
size_t count;
A stack[];
}B;
B *createStack(size_t size)
{
B *s = malloc(sizeof(*s) + size * sizeof( s -> stack[0]));
return s;
}
void rr(B* test) {
for (unsigned int i = 0; i < 4; i++) {
(test->stack+ i)->x= 89;
}
}
int main(void)
{
B *stack = createStack(4);
rr(stack);
free(stack);
}
You need only one allocation to mallloc/realloc or free the structure. The array will decay into pointer for your assignment in rr function.

C language error: request for member ‘value’ in something not a structure or union

I got really confused why I can not use while loop to access the entire value for reading all of struct...Thank you guys... I think about 3 hours but have no clue. I do not know why does the value is not realized by the program, since I already defined that this is a struct.
#include <stdio.h>
struct card{
int isRed;
int hasLetter;
union{
int charValue;
int intValue;
}value;
};
typedef struct card typeCard;
int deckValue(typeCard *deck[])
{
int i = 0;
int sum = 0;
while(deck[i] != NULL){
sum += deck[i].value.intValue;
i += 1;
}
return sum;
}
int main()
{
int sum;
typeCard card1 = {.isRed = 1,.hasLetter = 0,.value.intValue = 200};
typeCard card2 = {.isRed = 100,.hasLetter = 0,.value.intValue = 200};
typeCard deck[] = {card1,card2,NULL};
sum = deckValue(deck);
printf("%d",sum);
return 0;
}
The problem is that the parameter to your function:
int deckValue(typeCard *deck[])
Doesn't match how you're using it:
sum += deck[i].value.intValue;
The function definition says that desk is an array of pointers to typeCard. So when you do deck[i].value it thinks that you have an array of typeCard.
You instead want:
sum += deck[i]->value.intValue;
This will dereference the pointer for the array element.
Also in main, you're not passing an array of pointers to typeCard:
typeCard deck[] = {card1,card2,NULL};
sum = deckValue(deck);
You're passing an array of typeCard. Since you want an array of pointers so you can use a NULL pointer as a sentinel, you need to change the definition to an array of pointers, and initialize the array elements accordingly:
typeCard *deck[] = {&card1, &card2, NULL};

C how to allocate struct to struct?

The following code gives me a Compile error "incompatible types at assignment"
File 1:
struct x{
int a;
int b;
int c;
};
File 2:
static struct x d;
void copyStructVal(){
d-> a = 1;
d-> b = 2;
d-> c = 3;
}
x getStruct(){
copyStructVal();
return d;
}
File 3:
static struct x e;
void copy(){
e = getStruct();
}
I've searched for this and can't find the answer. Can I do it with a Pointer? (I'm a amateur in C)
In C, you need to write struct behind the name of a structure, unless you typedef it. In other words:
x getStruct(){
Must be:
struct x getStruct(){
Since you wrote it in the rest of the code, I guess it is a typo.
On top of that, you have to fix these 3 lines, since d is not a pointer:
d-> a = 1;
d-> b = 2;
d-> c = 3;
They should be:
d.a = 1;
d.b = 2;
d.c = 3;

Accessing a pointer to a figure from another figure in C

I am trying to access my struct points. The structs memory are dynamically located. I am getting a segmentation fault that I can't figure out. My struct definitions from my .h file are as follows:
struct point{
double x;
double y;
};
struct figure{
char name[128];
int draw;
struct point *points;
};
extern struct figure *figures;
In my .c file I have:
struct figure *figures;
//initializing 10 figures
figures = malloc(10 * sizeof(struct figure));
//left the obvious NULL checking out for brevity
//I'm fairly sure this portion works for initializing 10 points for each figure
int i;
for(i = 0;i<10;i++){
figures[i].points = malloc(10 * sizeof(struct point));
//left out NULL checking again
}
Unless a problem was detected before this point this is where I am having trouble, actually storing values into points.
NOTE: index could be any int >= 0, just using a general term for simplicity
figures[index].points[index]->x = 10;
figures[index].points[index]->y = 15;
Any help with his problem would be fantastic. Thanks in advance.
figures[index].points is an array of structures, which means that indexing it (i.e. figures[index].points[index]) gives you a structure. The last two lines should be:
figures[index].points[index].x = 10;
figures[index].points[index].y = 15;
I'm surprised the compiler wouldn't catch this.
Apart from the fact that you are accessing the inner structure incorrectly,I don't see any problem in this code.
Online Demo of your code sample that works.
#include<string.h>
#include<stdio.h>
struct point{
double x;
double y;
};
struct figure{
char name[128];
int draw;
struct point *points;
};
int main()
{
struct figure *figures;
figures = malloc(10 * sizeof(struct figure));
int i = 0;
for(i = 0;i<10;i++)
{
figures[i].points = malloc(10 * sizeof(struct point));
figures[i].draw = i;
}
i = 0;
for(i = 0;i<10;i++)
{
printf("\nfigures[%d].draw = [%d]",i,figures[i].draw);
int j;
for(j = 0;j<10;j++)
{
figures[i].points[j].x = i;
figures[i].points[j].y = j;
printf("\nfigures[%d].points[%d].x = [%f]",i,j,figures[i].points[j].x);
printf("\nfigures[%d].points[%d].y = [%f]",i,j,figures[i].points[j].y);
}
}
return 0;
}
Output:
figures[0].draw = [0]
figures[0].points[0].x = [0.000000]
figures[0].points[0].y = [0.000000]
figures[0].points[1].x = [0.000000]
figures[0].points[1].y = [1.000000]
figures[0].points[2].x = [0.000000]
...so on

typecasting structs to obtain individual field addresses

#include<stdio.h>
#include<stdlib.h>
struct test{
char b;
int a;
int c ;
};
int main()
{
struct test inst;
struct test *ptr_test = &inst;
char * ptr_ch;
int* ptr_i;
/*ptr_ch = (char *) ptr_test;*/
ptr_ch = (char*)ptr_test;
ptr_i = (int *) ptr_test;
*ptr_ch = 'b';
*ptr_i = 13;
printf("char b = %c, int a = %d int c = %d", inst.b, inst.a, inst.c);
return 0;
}
I expected the output to give the appropriate values of a,b and garbage value of c.
But on the terminal, if I do ./a.out the output is:
, int a = 134513785 int c = 13173540
When I do $./a.out > tmp; vim tmp, the output is:
char b = ^M, int a = 134513785 int c = 12714788
What is the problem?
I wanted to access individual fields of the struct using typecasting.
for instance, I wanted to know another way to return the value of &(inst.a).
Your pointers
ptr_ch = (char*)ptr_test;
ptr_i = (int *) ptr_test;
do not automatically refer to the first apropriate member variable (in your case b and a). Rather they just reinterpret the pointer to the structure as pointer to char or int, so they point to the same location, the address of your structure. With the char you might be lucky that it's the first member and you are really pointing to the char, but your int pointer points to the same address and therefore overwrites it with platform- and compiler-dependent garbage.
So don't do those kinds of things (or do them when you really know what you are doing and, more important, where (on what platform and with what compiler) you are doing it).
ptr_ch and ptr_i point to the same memory location:
ptr_ch = (char*)ptr_test;
ptr_i = (int *) ptr_test;
when you do the following you are reading from the same memory address:
*ptr_ch = 'b'; //write the first sizeof(char) byte of the structure ptr_test
*ptr_i = 13; //write the first sizeof(int) bytes of the structure ptr_test overwriting some bytes wrote before
You should eventually do something like:
ptr_ch = &(ptr_test->b);
*ptr_ch = 'b';
ptr_i = &(ptr_test->a);
*ptr_i = 13;
Why would you use the typecasting? Why not do the following:
ptr_ch = &(ptr_test->b);
ptr_i = &(ptr_test->a);
13 is decimal for an ASCII carriage return - when you do *ptr_i = 13;, you're setting b to that 13. If you change your print out to look like:
printf("char b = %c (%d), int a = %d int c = %d", inst.b, inst.b, inst.a, inst.c);
You'll see that you get:
(13), int a = 1 int c = 1606416024
as output instead. The carriage return character is causing your char b output to get overwritten by the output following the carriage return character. It might be more obvious if you used a different number than 13. For example, using 86, you'll get:
char b = V, int a = 1 int c = 1606416024
as the output. The reason a and c don't make sense is because they're uninitialized.
You can't just typecast a structure pointer to a pointer of another type and expect the compiler to extract a pointer to a field inside that structure for you - that's not how it works. I think you might have been trying to do this:
ptr_ch = &ptr_test->b;
ptr_i = &ptr_test->a;
Here's a complete example program that does what I think you're trying for:
#include<stdio.h>
struct test {
char b;
int a;
int c;
};
int main(void)
{
struct test inst = {0, 0, 0};
struct test *ptr_test = &inst;
char *ptr_ch;
int *ptr_i;
ptr_ch = &ptr_test->b;
ptr_i = &ptr_test->a;
*ptr_ch = 'b';
*ptr_i = 86;
printf("char b = %c, int a = %d int c = %d\n", inst.b, inst.a, inst.c);
return 0;
}
And its output:
char b = b, int a = 86 int c = 0
You should use the strict conforming offsetof macro, which calculates the offset of any struct element from struct begin:
ptr_ch = (char*)ptr_test;
*ptr_ch = 'b';
ptr_i = ptr_ch + offsetof(struct test,a);
*ptr_i = 13;
ptr_i = ptr_ch + offsetof(struct test,c);
*ptr_i = 14;

Resources