w3resource

C - Structures

Working with Structures

The majority of applications require the storage of data for future use.In most cases, this data is a logical grouping of related information, such as student information and item information.Storage and retrieval of such data would be easier if they were called structures, which are records that store information.Users can store and retrieve records from a file using the fread() and fwrite () functions.

This tutorial discusses how to work with structures. It also discusses how to use structures in file handling.

Table of Contents :

Structures

  • Arrays are collections of data items, all of which have the same data type and which are accessed by a common name and an integer index.
  • A struct consist of different data types and the individual fields may be accessed by name rather than integer index.
  • Structures are extremely useful for bundling together data items that collectively describe a thing, or are related in some way.

Properties of a structure:

  • the internal elements may consist of a variety of data types
  • the order of the elements is arbitrary (there is no indexing, as with arrays
  • a fixed size based on the combined sizes of the internal components

Defining Structures

Structures are defined using the struct construct of C. Consider the following record definition:

The most common and perhaps best way to define a new structure type involves naming it, with a tag, as shown in the following example:

/* A structure representing a record in a student database */
struct Student
  {
char f_name[20];// first name
char l_name[20];// last name
intid_number;	// social security number
double grade_point;	// grade point average
  };

In the example above, the tag for the newly defined struct is "student", and the names of the fields within the struct are f_name, l_name, id_number, and grade_point. It is important to note that the fields can be of different types, although this is not required.

At this point "struct Student " is a valid data type, and so variables can be declared of this type:

structStudent s1, s2, s3;

Furthermore, it is possible to create a struct type and declare variables of the type simultaneously:

struct Student

{
char f_name[20];
char l_name[20];
intid_number;	
double grade_point;	
  } nadira, cahaya, ris;

Since struct Student has been declared as a type, it is now possible to create additional variables of the same type:

struct Student jarl, osgar;

Additionally, it is possible to create struct variables without creating a named struct type. However, in this case, additional variables of the same type cannot be created, nor they can be passed to functions. In spite of the fact that other struct variables may be created with the same data types and field names in the same order, they are not considered as the same type:

struct   {
char f_name[20];
char l_name[20];
intid_number;	
double grade_point;	
  } dev, beth;

devand bethare of the same type, but not the same as struct Student.

struct   {
char f_name[20];
char l_name[20];
intid_number;	
double grade_point;	
  } andy, cindy;

andy and cindy are the same type as each other, but not anyone else.

Example: Create a struct variable with specific name

Code:

#include <stdio.h>
struct Student
  {
char f_name[20];     // first name
char l_name[20];     // last name
int id_number;	      // social security number
double grade_point;  // grade point average
  };
int main() {
struct Student S1;
return 0;
}

Accessing data fields within structs

The structure member operator . (dot) connects the structure nameand the member name.To access named fields within struct variables, the dot operator ( period ) is used:

  • S1.id_number = 123;

Example-1: Assign and access structure members

Code:

#include <stdio.h>
#include <string.h>
struct Student
  {
char f_name[20];     // first name
char l_name[20];     // last name
int id_number;	      // social security number
double grade_point;  // grade point average
  };

int main() {
struct Student S1, S2;
   // Assign values to members of S1

  // S1.f_name =  "Rosa";  throw a error message
  // [Error] incompatible types in assignment of 'const char [5]' to 'char [20]'
  // So use strcpy() function to assign the value to s1.f_name, s1.l_name

strcpy(S1.f_name, "Rosa");
strcpy(S1.l_name, "Rowe");
  S1.id_number = 123;
  S1.grade_point = 88.89;

  // Assign values to members of S2
strcpy(S2.f_name, "Kyla");
strcpy(S2.l_name, "Chavez");
  S2.id_number = 124;
  S2.grade_point = 91.56;

  // Print the values the members S1 
printf("Student details:\n");
printf("\nFirst name: %s", S1.f_name);
printf("\nLast name: %s", S1.l_name);
printf("\nSocial security number: %d", S1.id_number);
printf("\nGrade point average: %5.2f", S1.grade_point);

  // Print the values the members S2 
printf("\n\nFirst name: %s", S2.f_name);
printf("\nLast name: %s", S2.l_name);
printf("\nSocial security number: %d", S2.id_number);
printf("\nGrade point average: %5.2f", S2.grade_point);
return 0;
}

Output:

Student details:

First name: Rosa
Last name: Rowe
Social security number: 123
Grade point average: 88.89

First name: Kyla
Last name: Chavez
Social security number: 124
Grade point average: 91.56

Initializing variables of type struct

By enclosing multiple data fields in curly braces, structure variables can be initialized in much the same way as arrays. The simplest approach is to initialize all fields in the order they appear in the struct, and if only a portion of the struct is initialized, then all remaining fields are initialized to zero.

struct Student S1 = {"Rosa", "Rowe", 123, 88.89}, S2= {"Ryan", "Preston", 124}; // S2 has grade_point 0.0

C99 also allows the use of designated initializers in any order to initialize particular fields. The fields that are unnamed follow their predecessors in order.

Example:

Code:

#include <stdio.h>
struct Rectangle
{
int a, b, c, d;
};

int main()
{
   // Examples using designated initialization
struct Rectangle R1 = {.b = 0, .c = 1, .a = 2};
struct Rectangle R2 = {.a = 20, .c = 23, .b = 21, .d = 15};

printf ("a = %d, b = %d, c = %d, d = %d\n", R1.a, R1.b, R1.c, R1.d);
printf ("a = %d, b = %d, c = %d, d = %d\n", R2.a, R2.b, R2.c, R2.d);
return 0;
}

Output:

a = 2, b = 0, c = 1, d = 0
a = 20, b = 21, c = 23, d = 15

Example- 2: Assign and access structure members

Code:

#include <stdio.h>
#include <string.h>
struct Student
  {
char f_name[20];     // first name
char l_name[20];     // last name
int id_number;	      // social security number
double grade_point;  // grade point average
  };

int main() {

   // Assign values to members of S1
struct Student S1 = {"Rosa", "Rowe", 123, 88.89};

  // Assign values to members of S2
struct Student S2 = {"Kyla", "Chavez", 124, 91.56};

  // Print the values the members S1 
printf("Student details:\n");
printf("\nFirst name: %s", S1.f_name);
printf("\nLast name: %s", S1.l_name);
printf("\nSocial security number: %d", S1.id_number);
printf("\nGrade point average: %5.2f", S1.grade_point);

  // Print the values the members S2 
printf("\n\nFirst name: %s", S2.f_name);
printf("\nLast name: %s", S2.l_name);
printf("\nSocial security number: %d", S2.id_number);
printf("\nGrade point average: %5.2f", S2.grade_point);
return 0;
}

Output:

Student details:
First name: Rosa
Last name: Rowe
Social security number: 123
Grade point average: 88.89

First name: Kyla
Last name: Chavez
Social security number: 124
Grade point average: 91.56

Copy Structures

A structure can also be assigned to another. Here is an example where the values of S1 are copied to S2:

Code:

#include <stdio.h>
#include <string.h>
struct Student
  {
char f_name[20];     // first name
char l_name[20];     // last name
int id_number;	      // social security number
double grade_point;  // grade point average
  };

int main() {

   // Assign values to members of S1
struct Student S1 = {"Rosa", "Rowe", 123, 88.89};

  // the values of S1 are copied to S2:
struct Student S2;
  S2 = S1;

  // Print the values the members S1 
printf("Student details:\n");
printf("\nFirst name: %s", S1.f_name);
printf("\nLast name: %s", S1.l_name);
printf("\nSocial security number: %d", S1.id_number);
printf("\nGrade point average: %5.2f", S1.grade_point);

  // Print the values the members S2 
printf("\n\nFirst name: %s", S2.f_name);
printf("\nLast name: %s", S2.l_name);
printf("\nSocial security number: %d", S2.id_number);
printf("\nGrade point average: %5.2f", S2.grade_point);
return 0;
}

Output:

Student details:

First name: Rosa
Last name: Rowe
Social security number: 123
Grade point average: 88.89

First name: Rosa
Last name: Rowe
Social security number: 123
Grade point average: 88.89

Modify Values in a Structure:

You can use the dot syntax (.) to change or modify a value. The strcpy() function is again useful for modifying a string value:

Code:

#include <stdio.h>
#include <string.h>
struct Student
  {
char f_name[20];     // first name
char l_name[20];     // last name
int id_number;	      // social security number
double grade_point;  // grade point average
  };

int main() {

   // Assign values to members of S1
struct Student S1 = {"Rosa", "Rowe", 123, 88.89};
printf("Values before modification:");
printf("\nFirst name: %s", S1.f_name);
printf("\nLast name: %s", S1.l_name);
printf("\nSocial security number: %d", S1.id_number);
printf("\nGrade point average: %5.2f", S1.grade_point);

 // Modify values
strcpy(S1.f_name, "Ryan");
strcpy(S1.l_name, "Preston");
  S1.id_number = 130;
  S1.grade_point = 87.00;

printf("\n\nValues after modification:");
printf("\nFirst name: %s", S1.f_name);
printf("\nLast name: %s", S1.l_name);
printf("\nSocial security number: %d", S1.id_number);
printf("\nGrade point average: %5.2f", S1.grade_point);

return 0;
}

Output:

Values before modification:
First name: Rosa
Last name: Rowe
Social security number: 123
Grade point average: 88.89

Values after modification:
First name: Ryan
Last name: Preston
Social security number: 130
Grade point average: 87.00

typedef with structs

C provides a facility called typedef for creating new data type names. In this case, a new name for an existing data type is created, not a new data type.

Declaration and example:

  • typedef int Integer;
  • Integer no_of_students, total_marks;

Scope of struct type definitions

  • Struct type definitions (whether or not they use typedef) follow the same rules as variable declarations.
  • This means that variables of that type cannot be declared until the struct definition is within scope.

Example typedef with structs:

In the following example we have used typedef with the Student structure to create an alias Student.

typedef  struct Student  {
char f_name[20 ];
char l_name[20];
intid_number;	
double grade_point;	
  }Student;

It is now possible to create additional variables of the same type after typedefing struct Student to "Student":

Student sara, ryan;

Code:

#include <stdio.h>
#include <string.h>
typedef struct Student
  {
char f_name[20];     // first name
char l_name[20];     // last name
int id_number;	      // social security number
double grade_point;  // grade point average
  } Student;

int main() {	
  Student S1, S2;  
strcpy(S1.f_name, "Rosa");
strcpy(S1.l_name, "Rowe");
  S1.id_number = 123;
  S1.grade_point = 88.89;  
  // Assign values to members of S2
strcpy(S2.f_name, "Kyla");
strcpy(S2.l_name, "Chavez");
  S2.id_number = 124;
  S2.grade_point = 91.56; 
  // Print the values the members S1 
printf("Student details:\n");
printf("\nFirst name: %s", S1.f_name);
printf("\nLast name: %s", S1.l_name);
printf("\nSocial security number: %d", S1.id_number);
printf("\nGrade point average: %5.2f", S1.grade_point);  
  // Print the values the members S2 
printf("\n\nFirst name: %s", S2.f_name);
printf("\nLast name: %s", S2.l_name);
printf("\nSocial security number: %d", S2.id_number);
printf("\nGrade point average: %5.2f", S2.grade_point);
return 0;
}

Nested Structs:

Several structures may be nested within each other, either with previously defined structures or with newly defined structures. It is possible to avoid using the struct names in the latter case, but scoping rules should still be followed.

Example: Nested Structs

Code:

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

struct Marks {
int science;
int math;
int language;
};

struct Student {
	char name[40]; 
int id_number;	
struct Marks marks;  
} student;

int main() {

  // initialize student Marks
  student.marks.science = 92;
  student.marks.math = 97;
  student.marks.language = 89;

  // initialize student details
strcpy(student.name, "Rosa Rowe");
  student.id_number = 123;

  // Print the values the members student 	
printf("Student details:\n");
printf("\nName: %s", student.name);
printf("\nStudent ID: %d", student.id_number);
printf("\nMarks in Science: %d", student.marks.science);
printf("\nMarks in Math: %d", student.marks.math);
printf("\nMarks in Language: %d", student.marks.language);
return 0;
}

Output:

Student details:

Name: Rosa Rowe
Student ID: 123
Marks in Science: 92
Marks in Math: 97
Marks in Language: 89

Previous: C Arrays and Pointers
Next: C Library type Home



Share this Tutorial / Exercise on : Facebook and Twitter

C Programming: Tips of the Day

What's an object file in C?

An object file is the real output from the compilation phase. It's mostly machine code, but has info that allows a linker to see what symbols are in it as well as symbols it requires in order to work. (For reference, "symbols" are basically names of global objects, functions, etc.)

A linker takes all these object files and combines them to form one executable (assuming that it can, i.e.: that there aren't any duplicate or undefined symbols). A lot of compilers will do this for you (read: they run the linker on their own) if you don't tell them to "just compile" using command-line options. (-c is a common "just compile; don't link" option.)

Ref : https://bit.ly/3CbzF8M