Learn C - C Structure Pointer






The following code defined pointer for a structure:

Dog *pDog = NULL;

This declares a pointer, pDog, that can store the address of a structure of type Dog.

Don't forget that the typedef for Dog is necessary to omit the struct keyword.

Without the typedef, you must write the statement as:

struct Dog *pDog = NULL;

You can now set pDog to have the value of the address of a structure:

Dog aDog = { 3, 11, "name", "C", "C++"}; 
pDog = &aDog; 

Here pDog points to the aDog structure.

The pointer could store the address of an element in the array of Dogs from the previous example:

pDog = &my_Dogs[1];

Now pDog points to the structure my_Dogs[1].

You can reference elements of this structure through your pointer.

printf("The name is %s.\n", (*pDog).name);

You could write the previous statement like this:

printf("The name is %s.\n", pDog->name );

-> is called the pointer to member operator.

Dynamic Memory Allocation for Structures

Dog *pDogs[3];

This statement declares an array of 3 pointers to structures of type Dog.

Only memory for the pointers has been allocated by this statement.

You must still allocate the memory necessary to store the actual members of each structure that you need.


#include <stdio.h> 
#include <ctype.h> 
#include <stdlib.h>               // For malloc() 
  /*  w w  w.j ava2 s  .  c  om*/
typedef struct Dog Dog;           // Define Dog as a type name 
  
struct Dog                        // Structure type definition 
{ 
  int age; 
  int height; 
  char name[20]; 
  char father[20]; 
  char mother[20]; 
}; 
  
int main(void) { 
  
  Dog *pDogs[3];                  // Array of pointers to structure 
  int hcount = 0;                 
  char test = '\0';               // Test value for ending input 
  
  for(hcount = 0 ; hcount < sizeof(pDogs)/sizeof(Dog*) ; ++hcount) { 
    printf("Do you want to enter details of a%s Dog (Y or N)? ", 
         hcount?"nother" : "" ); 
    scanf(" %c", &test, sizeof(test)); 
    if(tolower(test) == 'n') 
      break; 
    // allocate memory to hold a Dog structure 
    pDogs[hcount] = (Dog*) malloc(sizeof(Dog)); 
  
    printf("Enter the name of the Dog: " ); 
    scanf("%s", pDogs[hcount]->name, sizeof(pDogs[hcount]->name)); 
  
    printf("How old is %s? ", pDogs[hcount]->name ); 
    scanf("%d", &pDogs[hcount]->age); 
  
    printf("How high is %s ( in hands )? ", pDogs[hcount]->name); 
    scanf("%d", &pDogs[hcount]->height); 

    printf("Who is %s's father? ", pDogs[hcount]->name); 
    scanf("%s", pDogs[hcount]->father, sizeof(pDogs[hcount]->father)); 

    printf("Who is %s's mother? ", pDogs[hcount]->name); 
    scanf("%s", pDogs[hcount]->mother, sizeof(pDogs[hcount]->mother)); 
  } 
  // Now tell them what we know. 
  printf("\n"); 
  for (int i = 0 ; i < hcount ; ++i) { 
    printf("%s is %d years old, %d hands high,", pDogs[i]->name, pDogs[i]->age, pDogs[i]->height); 
    printf(" and has %s and %s as parents.\n", pDogs[i]->father, pDogs[i]->mother); 
    free(pDogs[i]); 
  } 
  return 0; 
} 

The code above generates the following result.





Structures As Members of a Structure

You can define a structure type designed to hold dates.

You can specify a suitable structure with the tag name Date with this statement:

struct Date 
{ 
  int day; 
  int month; 
  int year; 
}; 

You can also include a typedef for Date as well as for Dog:

typedef struct Dog Dog;       // Define Dog as a type name 
typedef struct Date Date;         // Define Date as a type name 

Now you can define the Dog structure, including a date-of-birth variable, like this:

  
struct Dog { 
  Date dob; 
  int height; 
  char name[20]; 
  char father[20]; 
  char mother[20]; 
}; 
  

Dog aDog; 
aDog.height = 14; 
aDog.dob.day = 5; 
aDog.dob.month = 12; 
aDog.dob.year = 1962; 

Pointers to Structures As Structure Members

Any pointer can be a member of a structure.

A pointer structure member that points to the same type of structure is also permitted.


#include <stdio.h> 
#include <ctype.h> 
#include <stdlib.h> 
  /*from   w w  w .  j a va 2s  . c om*/
typedef struct Dog Dog;            // Define Dog as a type name 
  
struct Dog                           // Structure type definition 
{ 
  int age; 
  int height; 
  char name[20]; 
  char father[20]; 
  char mother[20]; 
  Dog *next;                         // Pointer to next Dog structure 
}; 
  
int main(void) { 
  Dog *first = NULL;                 // Pointer to first Dog 
  Dog *current = NULL;               // Pointer to current Dog 
  Dog *previous = NULL;              // Pointer to previous Dog 
  
  char test = '\0';                    // Test value for ending input 
  
  for( ; ; ) { 
    printf("Do you want to enter details of a%s Dog (Y or N)? ", first != NULL?"nother" : "" ); 
    scanf(" %c", &test, sizeof(test)); 
    if(tolower(test) == 'n') 
      break; 
  
    // Allocate memory for a Dog structure 
    current = (Dog*) malloc(sizeof(Dog)); 
    if(first == NULL)                  // If there's no 1st Dog... 
      first = current;                 // ...set this as 1st Dog 
  
    if(previous != NULL)               // If there was a previous... 
      previous->next = current;        // ...set its next to this one 
  
    printf("Enter the name of the Dog: "); 
    scanf("%s", current->name, sizeof(current->name)); 

    printf("How old is %s? ", current->name); 
    scanf("%d", &current->age); 
      
    printf("How high is %s ( in hands )? ", current -> name ); 
    scanf("%d", &current->height); 
      
    printf("Who is %s's father? ", current->name); 
    scanf("%s", current->father,sizeof(current->father)); 
      
    printf("Who is %s's mother? ", current->name); 
    scanf("%s", current->mother, sizeof(current->mother)); 
      
    current->next = NULL;             // In case it's the last... 
    previous = current;               // ...save its address 
  } 
      
  // Now tell them what we know... 
  printf("\n"); 
  current = first;                    // Start at the beginning 
  while (current != NULL)             // As long as we have a valid pointer 
  { // Output the data 
    printf("%s is %d years old, %d hands high,", current->name, current->age, current->height); 
    printf(" and has %s and %s as parents.\n", current->father, current->mother); 
    previous = current;               // Save the pointer so we can free memory 
    current = current->next;          // Get the pointer to the next 
    free(previous);                   // Free memory for the old one 
    previous = NULL; 
  } 
  first = NULL; 
  return 0; 
} 

The code above generates the following result.





Passing Arrays of Structures

To pass an array of structures, simply supply the function prototype with a pointer to the structure, as demonstrated in the next modified program.


#include <stdio.h> 
#include <string.h> 
typedef struct employee { 
  int id; /*from w ww  . j a  v a 2  s.c om*/
  char name[10]; 
  float salary; 
} e; 

void processEmp( e * ); //supply prototype with pointer of structure type 

main() 
{ 
   e emp1[3] = {0,0,0}; 
   int x; 
   processEmp( emp1 ); //pass array name, which is a pointer 
   for ( x = 0; x < 3; x++ ) {  
      printf("\nID: %d\n", emp1[x].id); 
      printf("Name: %s\n", emp1[x].name); 
      printf("Salary: $%.2f\n\n", emp1[x].salary); 
   }
}

void processEmp( e * emp ) //function receives a pointer 
{ 
   emp[0].id = 123; 
   strcpy(emp[0].name, "A"); 
   emp[0].salary = 65.00; 
   emp[1].id = 234; 
   strcpy(emp[1].name, "B"); 
   emp[1].salary = 28.00; 
   emp[2].id = 456; 
   strcpy(emp[2].name, "C"); 
   emp[2].salary = 48.00; 
}