Basic structure question

Programming, for all ages and all languages.
Post Reply
chris

Basic structure question

Post by chris »

I'm not sure what the purpose of declaring structures in different ways is...

Code: Select all

typedef struct {
    int x;
} example;
and...

Code: Select all

struct example {
    int x;
};

typedef struct example EXAMPLE;
Tim

Re:Basic structure question

Post by Tim »

In the top one, you're declaring a struct type with no name, then declaring a typedef called "example" for it. In the bottom one, you're declaring a struct type called "struct example" and declaring a typedef called "EXAMPLE" for it. They both have the same result, so whichever one you choose depends on your style.

One thing though: the top structure can't be recursive. That is, this won't work:

Code: Select all

typedef struct {
    int x;
    example *next;
} example; /* 'example' isn't declared when it is used */
This is where the second form is necessary:

Code: Select all

typedef struct example
{
    int x;
    struct example *next;
} EXAMPLE;

/* or */

typedef struct example EXAMPLE;
struct example
{
    int x;
    EXAMPLE *next;
};
All of this applies to C. In C++, you don't need to type the word 'struct' before you use a struct, so the typedefs are unnecessary.
chris

Re:Basic structure question

Post by chris »

Thanks, that cleared that up. Although, I'm having a bit of trouble with a program I'm writing just for practice/fun or whatever (it's with linked lists). When I compile I get an error like this:

Code: Select all

ll.c:65: error: dereferencing pointer to incomplete type
It's printed for each time I do something like this:

Code: Select all

struct->member = somevar;
Here is the code:

Code: Select all

#include <stdio.h>
#include <stdlib.h> 

struct rectangle {
???int x;
???int y;
???int area;
???
???struct rectangle *next;
???struct rectangle *prev;
};

typedef struct rectangle rectangle_t;
typedef struct rectangle_t *RECT;

RECT add(RECT head, int x, int y);

int main(void)
{
???RECT head = NULL;
???int i;
???int x;
???int y;
???int total;
???
???printf("How many rectangles to define?: ");
???scanf("%d", &total);
???
???for (i = 0; i < total; i++) {
??????printf("X value: ");
??????scanf("%d", &x);
??????printf("Y value: ");
??????scanf("%d", &y);
??????
??????head = add(head, x, y);
???}
??????
???return 0;
}

RECT add(RECT head, int x, int y) 
{
???RECT new = NULL;
???
???if(!(new = (RECT) malloc(sizeof(rectangle_t)))) {
??????printf("Error allocating memory");
???}
???
???new->x = x;
???new->y = y;
???new->area = (x * y);
???
???if(head == NULL) {
??????head = new;
???} ?

   /* Incomplete */

   return head;?????
}
Thanks in advance.

One last thing. In your first code post, would "example" be able to be modified (example.x = somevar). Also, would "example" and "EXAMPLE" be able to be modified in your second code post; or just "EXAMPLE"?
User avatar
df
Member
Member
Posts: 1076
Joined: Fri Oct 22, 2004 11:00 pm
Contact:

Re:Basic structure question

Post by df »

an easier way to do it

Code: Select all

struct rectangle {
   int x;
   int y;
   int area;
   
   struct rectangle *next;
   struct rectangle *prev;
};

typedef struct rectangle rectangle_t;
typedef struct rectangle_t *RECT;
is

Code: Select all

typedef struct RECT{
   int x;
   int y;
   int area;
   
   struct RECT *next;
   struct RECT *prev;
} RECT;
you dont need multiple typedefs to declare it.

i also (this is DF stylewise speaking) stongly advise against declareing types as pointers.

eg your

Code: Select all

RECT add(RECT head, int x, int y)
have it as RECT*, which hides the pointer from anyone reading the source. Id rather know I'm dealing with a ptr...

id suggest either prefix it ptrRECT or dont delcrare it as typedef rectangle* RECT... dont hide the *, basically :)

if that makes sense.
-- Stu --
chris

Re:Basic structure question

Post by chris »

Hmm... I'm kind of confused now. I shouldn't use pointers at all in this program, but if I do i need to add the *'s?

Code: Select all

RECT *add(RECT *head, int x, int y);   // ?
Does this help the compile error I'm getting?
chris

Re:Basic structure question

Post by chris »

I was messing around a bit and it seems to work fine for the most part. Although, I'm not sure why what I did made a difference. Here is the code:

Code: Select all


#include <stdio.h>
#include <stdlib.h> 

struct rectangle {
???int x;??????/* Width */
???int y;??????/* Height */
???int area;   /* Rectangle area (x * y) */
???
???struct rectangle *next;??????/* Double-linked */
???struct rectangle *prev;
} rectangle;

typedef struct rectangle *RECT;

RECT add(RECT head, int x, int y);
void display(RECT head);

int main(void)
{
???RECT head = NULL;
???int i;
???int x;
???int y;
???int total;
???
???printf("How many rectangles to define?: ");
???scanf("%d", &total);
???
???for (i = 0; i < total; i++) {
??????printf("Rectangle #%d\n", i);
??????printf("\tX value: ");
??????scanf("%d", &x);
??????printf("\tY value: ");
??????scanf("%d", &y);
??????
??????head = add(head, x, y);
???}
???
???display(head);
???printf("\n");
??????
???return 0;
}

RECT add(RECT head, int x, int y) 
{
???RECT new = NULL;
???RECT tmp;?????????/* Used for looping */
???
???if (!(new = (RECT) malloc(sizeof(rectangle)))) {
??????printf("Error allocating memory");
??????exit(1);
???}
???
???new->x = x;
???new->y = y;
???new->area = (x * y);
???
???/* Don't forget we're working with a double-linked list */
??????
???if (head == NULL) {??????/* List empty; first node */
??????head = new;
??????new->next = NULL;   /* Redundent */
??????new->prev = NULL;
???} else {
??????if (new->area < head->area) {   /* Before first node */
?????????head->prev = new;
?????????new->next = head;
?????????head = new;
??????} else {??????????????????/* Needs to be added to the middle or end */
?????????tmp = head->next;
?????????
?????????if (tmp == NULL) {
????????????head->next = new;
????????????new->prev = head;
?????????} else {
????????????while (tmp->next != NULL) {
???????????????if (new->area < tmp->area) {
??????????????????new->next = tmp;
??????????????????new->prev = tmp->prev;
??????????????????tmp->prev->next = new;
??????????????????tmp->prev = new;
????????????
??????????????????break;
???????????????} else {
??????????????????tmp = tmp->next;
???????????????}
????????????}
????????????
????????????if (tmp->next == NULL) {?????????
???????????????if (new->area < tmp->area) {???/* Before last node */
??????????????????new->next = tmp;
??????????????????new->prev = tmp->prev;
??????????????????tmp->prev->next = new;
??????????????????tmp->prev = new;
???????????????} else {??????????????????/* Last node */
??????????????????tmp->next = new;
??????????????????new->prev = tmp;
??????????????????new->next = NULL;?????????/* Redundent */
???????????????}
????????????}
?????????}
??????}
???}
????????????
???return head;???
}

void display(RECT head)
{
???RECT current = head;
???int count = 0;
???
???if ( head == NULL ) {   /* Something really when wrong in add() */
??????printf("List empty; nothing to display.");
??????exit(1);
???}

???while (current != NULL) {
??????printf("\nNode: %d\n", count++);
??????printf("\tX Value: %d\n", current->x);
??????printf("\tY Value: %d\n", current->y);
??????printf("\tArea: %d", current->area);
??????
??????current = current->next;
???}
}
Post Reply