UMBC CMSC 313 -- Structures in C Previous | Next


Structures in C

OK, you know about structures, right? The are the way to get around the restrictions that an array has. An array is a collection of related information all of the same data type, is stored in contiguous memory, randomly accessed and is of a size fixed at compile time. Structures allow each element to have a different data type. It is fixed in size and is also stored in contiguous. (You can combine these and have an array of structures or a structure of arrays.)

struct foo
{
    short  a;          /* 2 bytes */
    int    b;          /* 4 bytes */
    char   c;          /* 1 byte  */
    int    d;          /* 4 bytes */
    char   e[ 6 ];     /* 6 bytes */
                       /* Total:  17 bytes, do the math */
};
  

Then you need to instantiate the structure

struct foo s;
  

The size of this structure is 17 bytes long if you add up the size of each element.

C Code

#include <stdio.h>
#include <string.h>

struct foo
{
    short  a;          /* 2 bytes */
    int    b;          /* 4 bytes */
    char   c;          /* 1 byte  */
    int    d;          /* 4 bytes */
    char   e[ 6 ];     /* 6 bytes */
                       /* Total:  17 bytes, do the math */
};

int main ( void )
{

    struct foo s, t;
    int        num;

    printf( "size of s = %d\n", sizeof( s ) );
    printf( "address of s = %x\n", (unsigned int)&s );
    printf( "    address of s.a = %x\n", (unsigned int)&s.a );
    printf( "    address of s.b = %x\n", (unsigned int)&s.b );
    printf( "    address of s.c = %x\n", (unsigned int)&s.c );
    printf( "    address of s.d = %x\n", (unsigned int)&s.d );
    printf( "    address of s.e = %x\n", (unsigned int)&s.e );
    
    s.a = -1;
    s.b = 0x12345678;
    s.c = 'A';
    s.d = 1000;
    strcat ( s.e, "abcde" );

    return 0;

}    

  

Run The Program!

size of s = 24
address of s = bfffdc40
    address of s.a = bfffdc40
    address of s.b = bfffdc44
    address of s.c = bfffdc48
    address of s.d = bfffdc4c
    address of s.e = bfffdc50

  

Say That Again

struct foo  /* address of s = bfffdc40 */
{
    short  a;          /* 2 bytes */ /* address of s.a = bfffdc40 */  /* 4 */
    int    b;          /* 4 bytes */ /* address of s.b = bfffdc44 */  /* 4 */
    char   c;          /* 1 byte  */ /* address of s.c = bfffdc48 */  /* 4 */
    int    d;          /* 4 bytes */ /* address of s.d = bfffdc4c */  /* 4 */
    char   e[ 6 ];     /* 6 bytes */ /* address of s.e = bfffdc50 */  /* 8 */
                       /* Total:  17 bytes, do the math */   /* size of s = 24 */
};
  

Stupid Compiler!

Maybe. If you look at the addresses, everything (no matter what size) starts on a quad-byte boundary! The way that the Intel processors are designed, they run faster when 16-bit accesses are on a even address and 31-bit accesses are on a quad-byte boundary! Yes, we have wasted 7 bytes here, but some of the instructions actually take more bytes when the addresses match the rules of speed. Because we have so much memory today (1GB, more or less) compared to the old days (64KB), 7 bytes is not significant. Depending on the program, the time saved can be enough to be important.

When you are optimizing a program by looking at bytes Vs the time of the instructions, you want to optimize for speed. Simply put, a few thousand bytes today does not matter, since we have virtual machines that tells us we have 4GB of memory. Time is more important. (The trade-off is always memory vs. time.)

However, when optimizing a program, it is more important to make sure you have to best algorithm! Comparing instructions to see which version has the best time is a low-level optimization. Comparing algorithms is high-level optimization! The difference in low-level versions is measured in nanoseconds or milliseconds. The differences in algorithms can be measures in orders of magnitude! One algorithm can be 1000 times faster than another algorithm. (The classic example is to compare the bubble sort to the binary sort!)


Previous | Next

©2005, Gary L. Burt