Você está na página 1de 6

All about structures

All about Structures Structures are a convenient way of grouping together related variables of possibly differing types. For example, if you wanted to create a single variable that represents a person, a structure is ideal. Such a variable would need several sub-variables, for example:

Person Name Age Height

Creating structures Well, this is easily done with a simple structure declaration:

struct Person { char *name; int age; float height; };

As you ll notice, a structure declaration begins with the !eyword struct followed by the name of the structure. "he name is optional. "his sounds weird until you reali#e that a structure declaration defines a type. $n other words, you can declare variables right after the closing brace: struct { char *name; int age; float height; } Prelude, Generic_person;

%ne thing to note however, is that if you omit the name &also !nown as the structure tag' from the declaration, you must declare variables of the structure in the same declaration. "o declare variables of the structure later, you need the name of a type in one of two ways: With a structure tag:

struct Person { char *name; int age; float height; };

struct (erson (relude) With a typedef:

typedef struct { char *name; int age; float height; } Person_t; Person_t Prelude;

*oth of these examples re+uire some explanation. "he first declares a structure ,ust as we ve been tal!ing about, but it doesn t include the declaration of a structure variable. *ecause the structure has a tag, we can declare a structure variable later, but the struct !eyword is re+uired to tell the compiler that (erson is a structure. "his restriction is removed by -.., but the - solution is to use a typedef, which ta!es us to the second example. While it may loo! funny, using a typedef with a structure declaration is exactly the same as with any other type. $t helps to remove the member variables and get a good loo! at the structure of the typedef:

typedef int INT; typedef struct {} STRUCT;

*oth are the same: the typedef !eyword followed by the type to create an alias for, and finally the alias itself. *ut with larger structures this can become difficult to read, so the declaration is bro!en up into separate lines and indented to be readable as in our example above. Also notice that the struct !eyword isn t needed when using the alias, this is because the !eyword was included as a part of the typedef, adding another would be redundant and an error because (erson/t isn t a struct, it s a typedef of a struct. 0i!e any variable, structure variables can be initiali#ed with a list enclosed in braces:

struct Person Prelude = {"Prelude", 25, 5.9f};

$nitiali#ation is exactly the same when a variable is declared directly within the structure declaration: struct { char *name; int age; float height; } Prelude = {"Prelude", 25, 5.9f};

A structure variable can also be initiali#ed by assigning an existing structure variable &in which a copy is made' or by calling a function that returns a structure of the same type. Accessing structure variables 1ow that we have a structure variable, it would be a good idea to try and get access to the member variables. $f that weren t possible, structures wouldn t be very useful. "o get to a particular member of a structure, the structure-name.member syntax is used, also called the dot operator:

printf ( "Name: %s\n", Prelude.name ); printf ( "Age: %d years\n", Prelude.age ); printf ( "Height: %.2f feet\n", Prelude.height );

1otice that the variable name, not the structure tag, goes on the left side of the dot operator and the member name goes on the right side. Structures can be nested inside of each other as well: struct Person { char *name; int age; struct Height { int feet; int inches; } height; }; or struct Height { int feet; int inches; } struct Person { char *name; int age; struct Height height; };

When using the dot operator to access nested structures, ,ust start on the left side with the outermost structure and go in: printf ( "%d Inches\n", Prelude.height.inches );

When accessing a pointer to a structure, the pointer must first be dereferenced before the dot operator is used: struct Person *Prelude; ... printf ( "Name: %s\n", (*Prelude).name );

1ow, using this &2structure-name'.member syntax is aw!ward, ugly, and adds even more unnecessary parentheses to a language that already overuses them. So a special operator was added to the language because accessing the member of a pointer to a structure is so common and useful, structure-name-3member, also called the arrow operator. 1ow we don t need to explicitly dereference the pointer or surround it with parentheses: printf ( "Name: %s\n", Prelude->name );

Structures and Functions 4ust li!e any other type, structures can be assigned to each other as well as passed to and returned from functions or have pointers to them passed to and returned from functions. "here are three ways a structure can be passed to a function:

5ember by member:

void print_person ( { printf ( "Name: printf ( "Age: printf ( "Height: }

char *name, int age, float height ) %s\n", name ); %d years\n", age ); %.2f feet\n", height );

print_person ( Prelude.name, Prelude.age, Prelude.height );

Structure by value: void print_person ( { printf ( "Name: printf ( "Age: printf ( "Height: } struct Person pers ) %s\n", pers.name ); %d years\n", pers.age ); %.2f feet\n", pers.height );

print_person ( Prelude );

Structure by simulated reference: void print_person ( { printf ( "Name: printf ( "Age: printf ( "Height: } struct Person *pers ) %s\n", pers->name ); %d years\n", pers->age ); %.2f feet\n", pers->height );

print_person ( &Prelude );

"he preferred method in most cases is to pass a pointer to the structure. "his saves space for larger structures and can often be faster. $n fact, most data structure libraries will have a ma!e/node type function that allocates memory to a pointer and returns it, or ta!es a pointer to a pointer and allocates memory to that: struct Node *make_node ( void ) { struct Node new_node = malloc ( sizeof *new_node ); /* Error check and set a default state */ return new_node; } or int make_node ( struct Node **new_node ) { int rc = EXIT_SUCCESS; new_node = malloc ( sizeof *new_node ); /* Error check and set a default state */ return rc; }

%r something along those lines. :' "his often simplifies the logic of such data structure algorithms as lin!ed lists and binary trees, but becomes far more useful with sparse matrices and s!ip lists. Arrays of Structures 0i!e any other type, you can ma!e arrays of structures. "he syntax is the same as with regular arrays:

struct Person { char *name; int age; float height; } people[] = { {"Prelude", 25, 5.9f}, {"Generic person", 20, 6.0f} }; Or struct Person { char *name; int age; float height; }; struct Person people[] = { {"Prelude", 25, 5.9f}, {"Generic person", 20, 6.0f} };

"o access an individual member, be sure to index the array before using the dot operator: printf ( "Name: %s\n", people[0].name );

Miscellany 4ust in case there is still some confusion, structures and structure variables can be declared locally if need be:

#include <stdio.h> int main ( void ) { struct Person { char *name; int age; float height; }; struct Person Prelude = {"Prelude", 25, 5.9f}; printf ( "Name: %s\n", Prelude.name ); printf ( "Age: %d years\n", Prelude.age ); printf ( "Height: %.2f feet\n", Prelude.height );

return 0; }

Structures can contain pointers to a structure of the same type. Also called a self-referential structure: struct Node { void *data; struct Node *next; };

"his is a typical node structure for a single item in a lin!ed list. While this feature may seem confusing, !eep in mind that when a 1ode variable is declared, only a pointer to a 1ode is created for the member, not an actual 1ode. $f an actual 1ode were created, you would have a recursive declaration, and 1odes would be created until you run out of memory. *ut a pointer is safe because it doesn t behave recursively in this situation. "wo different structures can refer to each other. "his is handled in much the same way as a structure referring to itself:

struct a { struct b *p; }; struct b { struct a *p; };

"here is another feature of structures that can be useful sometimes called bit-fields. "hey re an advanced topic that $ will cover in another tutorial, along with another type of structure called a union.

Você também pode gostar