C Programming/Complex types

From Wikibooks, the open-content textbooks collection

Jump to: navigation, search
Previous: Strings Index Next: Networking in UNIX

Contents

[edit] Complex Types

< Programming:C

In the section C types we looked at some basic types. However C complex types allow us greater flexibility in managing data in our C program.

[edit] Data structures

A data structure ("struct") contains multiple pieces of data. Each piece of data (called a "member") can be accessed by the name of the variable, followed by a '.', then the name of the member. (Another way to access a member is using the member operator '->'). The member variables of a struct can be of any data type and can even be an array or a pointer.


[edit] Pointers

Pointers are variables that don't hold the actual data. Instead they point to the memory location of some other variable. For example,

   int *pointer = &variable;

defines a pointer to an int, and also makes it point to the particular integer contained in variable.

The '*' is what makes this an integer pointer. To make the pointer point to a different integer, use the form

   pointer = &sandwiches;

Where & is the address of operator. Often programmers set the value of the pointer to NULL (a standard macro defined as 0 or (void*)0 ) like this:

   pointer = NULL;

This tells us that the pointer isn't currently pointing to any real location.

Additionally, to dereference (access the thing being pointed at) the pointer, use the form:

   value = *pointer;

[edit] Structs

A data structure contains multiple pieces of data. One defines a data structure using the struct keyword. For example,

   struct mystruct
   {
       int int_member;
       double double_member;
       char string_member[25];
   } variable;

variable is an instance of mystruct. You can omit it from the end of the struct declaration and declare it later using:

struct mystruct variable;

It is often common practice to make a type synonym so we don't have to type "struct mystruct" all the time. C allows us the possibility to do so using a typedef statement, which aliases a type:

typedef struct
{
  ...
} Mystruct;

The struct itself has no name (by the absence of a name on the first line), but it is aliased as Mystruct. Then you can use

Mystruct variable;

Note that it is commonplace, and good style to capitalize the first letter of a type synonym. However in the actual definition we need to give the struct a tag so we can refer to it: we may have a recursive data structure of some kind.

[edit] Unions

The definition of a union is similar to that of a struct. The difference between the two is that in a struct, the members occupy different areas of memory, but in a union, the members occupy the same area of memory. Thus, in the following type, for example:

union {
    int i;
    double d;
} u;

The programmer can access either u.i or u.d, but not both at the same time. Since u.i and u.d occupy the same area of memory, modifying one modifies the value of the other, sometimes in unpredictable ways.

The size of a union is the size of its largest member.

[edit] Type modifiers

register is a hint to the compiler to attempt to optimise the storage of the given variable by storing it in a register of the computer's CPU when the program is run. Most optimising compilers do this anyway, so use of this keyword is often unnecessary. In fact, ANSI C states that a compiler can ignore this keyword if it so desires -- and many do. Microsoft Visual C++ is an example of an implementation that completely ignores the register keyword.

volatile is a special type modifier which informs the compiler that the value of the variable may be changed by external entities other than the program itself. This is necessary for certain programs compiled with optimisations - if a variable were not defined volatile then the compiler may assume that certain operations involving the variable were safe to optimise away when in fact they aren't. volatile is particularly relevant when working with embedded systems (where a program may not have complete control of a variable) and multi-threaded applications.

auto is a modifier which specifies an "automatic" variable that is automatically created when in scope and destroyed when out of scope. If you think this sounds like pretty much what you've been doing all along when you declare a variable, you're right: all declared items within a block are implicitly "automatic". For this reason, the auto keyword is more like the answer to a trivia question than a useful modifier, and there are lots of very competent programmers that are unaware of its existence.

extern is used when a file needs to access a variable in another file that it may not have #included directly. Therefore, extern does not actually carve out space for a new variable, it just provides the compiler with sufficient information to access the remote variable.

Previous: Strings Index Next: Networking in UNIX
In other languages