Structures in C Programming

A structure in C is a user-defined type that groups related values, potentially of different data types, under one name. For example, a student record can contain an integer roll number, a character array for the name, and a floating-point fee.

Structures are useful when several values describe one logical record. Unlike an array, whose elements have one element type, a structure can contain members with different types. Every structure member still retains its own type and storage.

How to Declare a Structure in C

A structure declaration starts with the struct keyword, followed by an optional tag and a member list enclosed in braces. A semicolon is required after the closing brace.

</>
Copy
 struct structname {
 	datatype varname1;
 	datatype varname2;
 	. . .
 };
  • Each variable declared inside the braces is called a structure member.
  • The type declaration describes the layout but does not by itself create a structure object.
  • Storage is allocated when a variable of the structure type is defined.
  • Each structure variable has its own copy of the non-static members.

C Structure Example for a Student Record

The following declaration defines a structure tagged student. It acts as a template for student records.

</>
Copy
struct student {
	int rollno;
	char name[20];
	char course[20];
	float fee;
};

The structure contains a roll number, name, course, and fee. These members use several C data types but belong to the same student record.

Once the type has been declared, a variable named stud1 can be defined as follows:

struct student stud1;

Multiple variables may be declared from the same structure type. For example, struct student stud1, stud2; creates two independent student records.

Initializing a Structure in C

A structure variable can be initialized when it is defined by listing values in member-declaration order. If fewer initializers are supplied, the remaining members are zero-initialized. This rule applies to initialized structure objects; an uninitialized automatic local structure otherwise contains indeterminate values. Objects with static storage duration are zero-initialized automatically.

  • Providing values for only the first members is called partial initialization; all omitted members are initialized as if they were assigned zero.
  • A member of a structure object is accessed with the dot operator, as in stud1.fee.
  • An aggregate initializer must follow member order unless designated initializers are used.
</>
Copy
struct structname {
	datatype varname1;
	datatype varname2;
	. . .
} structvar={constant1,constant2, . .};

C Structure Initialization Example

</>
Copy
struct student {
	int rollno;
	char name[20];
	char course[20];
	float fee;
} stud1={02,"john","CSE",4500};

stud1 is a variable of type struct student. Its members receive the values in declaration order: roll number, name, course, and fee. In modern C code, decimal integer values are normally written without a leading zero.

Designated Initializers for Structure Members

C99 and later support designated initializers. They identify members by name, make the assignment easier to review, and allow the initializers to appear in a different order.

</>
Copy
struct student stud2 = {
    .fee = 6200.0f,
    .rollno = 17,
    .name = "Maya",
    .course = "ECE"
};

Reading and Printing C Structure Members

The following program declares a student structure, reads values from standard input, stores them in a structure variable, and prints the members. The dot operator selects a member from the stud object.

C Program

</>
Copy
#include<stdio.h>

int main() {

	struct student{
		int rollno;
		char name[20];
		float fee;
		char dob[30];
	}stud;

	printf("\n Enter roll number:");
	scanf("%d",&stud.rollno);

	printf("\n Enter name:");
	scanf("%s",stud.name);

	printf("\n Enter fee:");
	scanf("%f",&stud.fee);

	printf("\n Enter DOB:");
	scanf("%s",stud.dob);

	printf("\n *******DETAILS**********");
	printf("\n Rollno=%d",stud.rollno);
	printf("\n Name=%s",stud.name);
	printf("\n Fee=%f",stud.fee);
	printf("\n DOB=%s",stud.dob);

	return 0;
}

A sample run produces output similar to the following:

Output

Enter roll number:01
Enter name:peter
Enter fee:10000
Enter DOB:31-08-1990

*******DETAILS**********
Rollno=1
Name=peter
Fee=10000.000000
DOB=31-08-1990

The unbounded %s conversion in this introductory example accepts a single whitespace-delimited word. In production code, limit the input width or use fgets() so that input cannot exceed the destination array and names can contain spaces.

Dot and Arrow Operators for C Structures

C provides two related member-access operators. Use . when working with a structure object and -> when working with a pointer to a structure. The expression ptr->fee is equivalent to (*ptr).fee; parentheses are required in the second form because the dot operator has higher precedence than unary *.

Value availableMember syntaxExample
Structure objectobject.memberstud.rollno
Pointer to structurepointer->memberptr->rollno
Dereferenced pointer(*pointer).member(*ptr).rollno

Pointer to a Structure in C

A pointer can hold the address of a structure object. Passing that pointer to a function avoids copying the complete structure and also allows the function to modify the original object. Whether this is preferable depends on the structure size and whether mutation is intended.

The following example stores the address of stud in ptr and uses the arrow operator to access its members.

C Program

</>
Copy
#include<stdio.h>

struct student{
	int rollno;
	char name[20];
	float fee;
	char dob[30];
}stud;

int main() {
	struct student *ptr;
	ptr=&stud;

	printf("\n Enter roll number:");
	scanf("%d",&ptr->rollno);

	printf("\n Enter name:");
	scanf("%s",ptr->name);

	printf("\n Enter fee:");
	scanf("%f",&ptr->fee);

	printf("\n Enter DOB:");
	scanf("%s",ptr->dob);

	printf("\n\n *******DETAILS**********");

	printf("\n Rollno=%d",ptr->rollno);
	printf("\n Name=%s",ptr->name);
	printf("\n Fee=%f",ptr->fee);
	printf("\n DOB=%s",ptr->dob);

	return 0;
}

A sample run produces:

Output

Enter roll number:02
Enter name:john
Enter fee:20000
Enter DOB:12-03-1990

*******DETAILS**********
Rollno=2
Name=john
Fee=20000.000000
DOB=12-03-1990

Passing a Structure Pointer to a C Function

The next program dynamically allocates a student object and passes its address to display(). A function receiving a structure pointer can read or change the original object through that pointer.

  • The address of the structure object is passed as the function argument.
  • The matching parameter has pointer-to-structure type.
  • Use a pointer to const when the called function should only inspect the members.

Note: Changes made through a non-const pointer are visible to the caller. Dynamically allocated storage should be checked for allocation failure and released with free() when it is no longer required.

C Program

</>
Copy
#include<stdio.h>
#include<malloc.h>

typedef struct student{
	int rollno;
	char name[20];
	float fee;
	char dob[30];
};

void display(struct student *);

int main() {
	struct student *ptr;

	ptr=(struct student *)malloc(sizeof(struct student));

	printf("\n Enter roll number:");
	scanf("%d",&ptr->rollno);

	printf("\n Enter name:");
	scanf("%s",ptr->name);

	printf("\n Enter fee:");
	scanf("%f",&ptr->fee);

	printf("\n Enter DOB:");
	scanf("%s",ptr->dob);

	display(ptr);

	return 0;
}

void display(struct student *ptr) {
	printf("\n *******DETAILS**********");
	printf("\n Rollno=%d",ptr->rollno);
	printf("\n Name=%s",ptr->name);
	printf("\n Fee=%f",ptr->fee);
	printf("\n DOB=%s",ptr->dob);
}

Output

Enter roll number:05
Enter name:ram
Enter fee:45000
Enter DOB:12-10-1980

*******DETAILS**********
Rollno=5
Name=ram
Fee=45000.000000
DOB=12-10-1980

Array of Structures in C

An array of structures stores multiple records of the same structure type in contiguous array elements. Each element is selected with an index, and the dot operator then selects a member from that element.

</>
Copy
#include <stdio.h>

struct product {
    int id;
    char name[24];
    double price;
};

int main(void) {
    struct product catalog[] = {
        {101, "Keyboard", 1499.00},
        {102, "Mouse", 749.50},
        {103, "Monitor", 12999.00}
    };

    size_t count = sizeof catalog / sizeof catalog[0];

    for (size_t i = 0; i < count; ++i) {
        printf("%d: %s - %.2f\n",
               catalog[i].id,
               catalog[i].name,
               catalog[i].price);
    }

    return 0;
}

The expression catalog[i].price first selects an array element and then accesses its price member. Arrays of structures are suitable for fixed-size collections of records. A dynamically allocated array can be used when the required number of records is known only at runtime.

Using typedef with a C Structure

A typedef creates an alias for a type. It can remove the need to repeat the struct keyword in later declarations, but it does not create a new object or allocate memory.

</>
Copy
typedef struct {
    int x;
    int y;
} Point;

Point start = {0, 0};
Point end = {12, 8};

Here, Point is an alias for the anonymous structure type. If the type needs to refer to itself, give it a structure tag or introduce an appropriate forward declaration.

Nested Structures in C

A nested structure contains another structure as one of its members. This is useful when a record includes a logical subrecord, such as a student containing a name and a date of birth.

The following declarations illustrate the basic arrangement.

C Program

</>
Copy
typedef struct NAME {
	char firstname[20];
	char lastname[20];
};

typedef  struct DATE {
	int dd;
	int mm;
	int yr;
};

typedef struct STUDENT {
	int roll;
	NAME name;
	DATE dob;
	float fee;
};

With a conforming C typedef declaration for each nested type, a nested value would be accessed through a chain such as stud.name.firstname or stud.dob.yr.

Self-Referential Structures in C

A self-referential structure contains a pointer to the same structure type. It cannot contain a complete instance of itself directly because that would require an object of infinite size. A pointer has a known, finite size, so it can link one object to another.

  • Self-referential structures are commonly used to build linked lists, trees, and graph nodes.

Example

</>
Copy
struct node {
    int value;
    struct node *next;
};

Here, next can point to another object of type struct node. A null pointer can represent the end of a linked list.

Example (doubly linkedlist)

</>
Copy
struct node {
    int value;
    struct node *next; //self referential
    struct node *prev;
};

In a doubly linked list, prev can refer to the preceding node and next can refer to the following node. The program managing the list is responsible for maintaining valid links and object lifetimes.

Structure Assignment and Function Arguments in C

C permits one structure object to be assigned to another object of the same compatible type. The values of all members, including array members, are copied. A structure can also be passed to or returned from a function by value.

</>
Copy
struct dimensions {
    double width;
    double height;
};

struct dimensions original = {8.5, 11.0};
struct dimensions copy = original;

copy.width = 10.0;

Changing copy.width does not change original.width because the assignment created a separate structure value. If a member is a pointer, however, the pointer value is copied rather than the separately allocated data to which it points.

C Structure Size, Alignment, and Padding

The size of a structure is not necessarily the sum of the visible member sizes. A C implementation may insert padding bytes between members or after the final member to satisfy alignment requirements. Use sizeof to obtain the actual size on the current implementation instead of calculating it manually.

Member order can affect the total size, but reordering members solely to reduce padding may make a public data format incompatible. Do not assume that an in-memory structure layout is a portable file or network representation. Define serialization explicitly when data must cross processes, machines, compilers, or architectures.

Advantages and Limitations of C Structures

AdvantagesLimitations and cautions
Groups different but related data types into one record.Padding can make the object larger than the sum of its members.
Allows records to be assigned, passed, returned, and stored in arrays.Passing a large structure by value copies it.
Supports nested and self-referential data models.A copied pointer member still refers to the same external allocation.
Gives members descriptive names instead of relying on array positions.Structure layout and padding are not automatically portable for binary storage.

Common C Structure Errors to Avoid

  • Omitting the semicolon after the closing brace of a structure declaration.
  • Using . with a pointer or -> with a non-pointer structure object.
  • Reading an uninitialized automatic structure member.
  • Assuming assignment duplicates dynamically allocated data referenced by pointer members.
  • Using an incorrect scanf() conversion specifier or allowing character input to overflow a member array.
  • Using a structure pointer after the pointed-to object has gone out of scope or has been freed.

C Structures Implementation Checklist

  • Confirm that every member has the correct C type and sufficient capacity.
  • Initialize every structure object before reading its members.
  • Use the dot operator for objects and the arrow operator for pointers.
  • Use bounded input operations for character-array members.
  • Document ownership rules for dynamically allocated data referenced by pointer members.
  • Use sizeof and explicit serialization instead of assuming a particular padded layout.

Frequently Asked Questions About C Structures

What is the purpose of using a struct in C?

A structure represents one record made from related values. It lets a program treat fields such as an employee ID, name, department, and salary as one object while preserving the data type of each field.

How do you declare a structure in C?

Use the struct keyword, an optional tag, a brace-enclosed member list, and a terminating semicolon. After declaring struct book, for example, an object can be defined with struct book item;.

What is the difference between an array and a structure in C?

An array contains a sequence of elements of one type and accesses them by index. A structure contains named members that may have different types. An array of structures combines both concepts to store multiple records of the same structure type.

What are the disadvantages of structures in C?

Structures may contain padding, copying large structures by value can have a cost, and pointer members require explicit lifetime and ownership management. Their binary memory layout can also differ between implementations, so it should not be treated as a portable storage format.

What does typedef struct mean in C?

It combines a structure declaration with a type alias. The alias allows later variables to be declared without repeating the struct keyword. It changes how the type is named, not how its members are stored.

Summary of C Structures

A C structure groups named members into one user-defined type. Structure objects use the dot operator, structure pointers use the arrow operator, and arrays of structures store collections of records. Nested structures model subrecords, while self-referential structures support linked data structures. This C Tutorial also covered initialization, typedef, structure assignment, padding, pointer safety, and common implementation errors.