Lecture 20 Structures

Joseph Haugh

University of New Mexico

Free Recall

Review Quiz

What is the output of the following code?

int x = 5;
int *y = &x;
int **z = &y;
printf("%d\n", **z);

Review Quiz

What is the output of the following code?

int x = 5;
int *y = &x;
int **z = &y;
printf("%d\n", **z);

5
Address Name Value
0x100 x 5
0x108 y 0x100
0x110 z 0x108

Review Quiz

What is the output of the following code?

int *x = 0x40;
int **y = &x;
printf("%p\n", **y);

Review Quiz

What is the output of the following code?

int *x = 0x40;
int **y = &x;
printf("%p\n", **y);

Segmentation fault
Address Name Value
0x100 x 0x40
0x108 y 0x100

Review Quiz

What is the output of the following code?

int *x;
int *y = x;
x = y;
printf("%p\n", *x);

Review Quiz

What is the output of the following code?

int *x;
int *y = x;
x = y;
printf("%p\n", *x);

Segmentation fault
Address Name Value
0x100 x NULL
0x108 y NULL

Review Quiz

What is the output of the following code?

int *x = 0x40;
int **y = &x;
x = *y;
printf("%p %p\n", x, *y);

Review Quiz

What is the output of the following code?

int *x = 0x40;
int **y = &x;
x = *y;
printf("%p %p\n", x, *y);

0x40 0x40
Address Name Value
0x100 x 0x40
0x108 y 0x100

Review Quiz

What is the output of the following code?

int x = 17;
int *y = &x;
int *z = y;
printf("%p\n", *z);

Review Quiz

What is the output of the following code?

int x = 17;
int *y = &x;
int *z = y;
printf("%p\n", *z);

0x11
Address Name Value
0x100 x 17
0x108 y 0x100
0x110 z 0x100

Reading

Section 6.1: Basics of structures

Structures

A structure is a collection of named data items.

/* x and y are members of the structure point. */
struct Point {int x; int y;};
/* A structure does not reserve storage. */
/* It only defines the type of storage. */

struct Point pt; /* This reserves storage.*/

Alternate syntax for defining and instantiating a structure.

struct Point { 
  int x; 
  int y; 
} pt;

Like class names in Java, in CS241, we will use structure names which start with a capital letter.

Accessing Members of a Structure

Individual members are accessed with the . operator.

struct Point { 
  int x; 
  int y; 
} pt;

/* Assignment to the members of a structure. */
pt.x = 5;
pt.y = 8;

/* Initializing a structure when it is instantiated. */
struct Point maxpt = {320, 200};

CS241 Coding Standard

Follows Standard:

struct Point { 
  int x; 
  int y; 
};
struct Point pt;

struct Point { 
  int x; 
  int y; 
} pt;

struct Point {int x; int y;} pt;

Does NOT follow Standard:

struct Point {
  int x; int y;
} pt;

Section 6.2: Structures and Functions

struct Point {int x; int y;}; 
struct Point makepoint(int x, int y) { 
  /* reuse of the variable names x and y is good. */
  struct Point temp;
  temp.x = x;   
  temp.y = y;
  return temp; /* Returned by value. */
} 

void main(void) { 
  struct Point p1 = makepoint(5,7);
  printf("p1=(%d, %d)\n", p1.x, p1.y);
}

Passing a Structure as an Argument

struct Point {int x; int y;}; 

void incrementPoint(struct Point p) { 
  p.x++;   
  p.y++;
} 

void main(void) { 
  struct Point p1 = {4, 7};
  incrementPoint(p1);
  printf("p1=(%d, %d)\n", p1.x, p1.y);
}

What is the output?

p1=(4, 7)

Section 6.4: Pointers to Structures

struct Point {int x; int y;}; 

void incrementPoint(struct Point *p) { 
  (*p).x++; /* . has higher precedence than *, */
            /* so *p.x++; is a syntax error. */
  /* Dereferencing a pointer, then accessing */
  /* a member is so common that it is given */
  /* a special notation. */
  p->y++;   
} 

void main(void) { 
  struct Point p1 = {4, 7};
  incrementPoint(&p1);
  printf("p1=(%d, %d)\n", p1.x, p1.y);
}

Output: p1=(5, 8)

Waring: Function Returns Address of Local Variable

struct Point {int x; int y;};

struct Point* badPointer(int x, int y) {
  struct Point temp; /* local var */
  temp.x = x;
  temp.y = y;
  return &temp; /* Oh, no! Returning address! */
}

void main(void) { 
  struct Point* p1 = badPointer(5,7);
  printf("p1->(%d, %d)\n", (*p1).x, (*p1).y);
}

Output: Segmentation fault

Section 6.3: Arrays of Structures

Parallel Arrays

char *keyword[NUM_KEYWORDS];
int  keycount[NUM_KEYWORDS]; 

Array of Structures

struct KeyStructure { 
  char *word; //allocates space for a pointer. 
  int  count;  
} key[NUM_KEYWORDS];

key[0].word= "if";   key[0].count = 0;
key[1].word= "for";  key[1].count = 0;
key[2].word= "char"; key[2].count = 0;
key[3].word= "int";  key[3].count = 0;

gcc Compile Error

#define NUM_KEYWORDS 32;
int main() { 
  struct KeyStructure
  { 
    char *word; 
    int count; 
  } key[NUM_KEYWORDS];
  /* Code continues below... */
foo.c: In function ‘main’:
foo.c:9: error: expected ‘]’ before ‘;’ token

What did I do wrong?

I put a semicolon after the #define statement.

Structure Operations

  • . and -> operators allow access to members of a structure.
  • Can be assigned, passed as parameters, and returned from functions. (i.e. structures are first class)
    • C is call-by-value, so structures are passed by value.
    • Often us a pointer to the structure instead
  • Structures cannot be compared with == or != operators.
    • You have to compare structures field by field.

Nested Structures

C allows structures to be nested.

struct Rect {
  struct Point bottomLeft;
  struct Point topRight;
};

struct Rect r;
r.bottomLeft.x = 0;

Self-Referential Structures

A structure cannot contain an instance of itself, but a structure declaration can contain a reference to its own (incomplete) type.

struct ListNode {
  int data; 
  struct ListNode* next;
};