# 2. Structures (struct)

### 2.1 What is a Structure?

A **structure** is a user-defined data type that groups variables of different types under a single name. Think of it as creating your own custom data type.

**Python vs C Comparison:**

| Python | C |
|--------|---|
| Uses classes or dictionaries | Uses `struct` |
| `student = {"name": "Alice", "age": 20}` | `struct Student student;` |
| Dynamic typing | Static typing |

### 2.2 Declaring a Structure

**Basic Syntax:**
```c
struct structure_name {
    data_type member1;
    data_type member2;
    // ... more members
};
```

**Example - Student Structure:**
```c
struct Student {
    int id;
    char name[50];
    float gpa;
    int age;
    char major[30];
};
```

**Important Notes:**
- Structure declaration ends with a semicolon `;`
- Members can be of any data type (including other structures)
- The structure declaration itself doesn't allocate memory

### 2.3 Creating Structure Variables

**Method 1: After Structure Declaration**
```c
struct Student {
    int id;
    char name[50];
    float gpa;
};

// Create variables
struct Student student1;
struct Student student2, student3;
```

**Method 2: During Structure Declaration**
```c
struct Student {
    int id;
    char name[50];
    float gpa;
} student1, student2;
```

**Method 3: Anonymous Structure (less common)**
```c
struct {
    int id;
    char name[50];
    float gpa;
} student1, student2;
```

### 2.4 Initializing Structure Variables

**Method 1: Member-by-Member Assignment**
```c
struct Student s1;
s1.id = 12345;
strcpy(s1.name, "Alice Johnson");  // Note: Use strcpy for strings
s1.gpa = 3.75;
```

**Method 2: Initialization at Declaration**
```c
struct Student s1 = {12345, "Alice Johnson", 3.75};
```

**Method 3: Designated Initializers (C99 and later)**
```c
struct Student s1 = {
    .id = 12345,
    .name = "Alice Johnson",
    .gpa = 3.75
};
```

**Method 4: Partial Initialization**
```c
struct Student s1 = {12345};  // Only id is initialized, others are 0/NULL
```

### 2.5 Accessing Structure Members

Use the **dot operator (`.`)** to access structure members:

```c
struct Student s1;

// Writing to members
s1.id = 12345;
s1.gpa = 3.75;
strcpy(s1.name, "Alice Johnson");

// Reading from members
printf("Student ID: %d\n", s1.id);
printf("Student Name: %s\n", s1.name);
printf("Student GPA: %.2f\n", s1.gpa);
```

### 2.6 Nested Structures

Structures can contain other structures as members:

```c
struct Date {
    int day;
    int month;
    int year;
};

struct Student {
    int id;
    char name[50];
    float gpa;
    struct Date birthDate;  // Nested structure
};

// Usage
struct Student s1;
s1.id = 12345;
s1.birthDate.day = 15;
s1.birthDate.month = 8;
s1.birthDate.year = 2003;

printf("Birth Date: %d/%d/%d\n", 
       s1.birthDate.day, 
       s1.birthDate.month, 
       s1.birthDate.year);
```

### 2.7 Array of Structures

You can create arrays of structures to handle multiple records:

```c
struct Student {
    int id;
    char name[50];
    float gpa;
};

// Array of 100 students
struct Student students[100];

// Accessing elements
students[0].id = 12345;
strcpy(students[0].name, "Alice");
students[0].gpa = 3.75;

// Loop through all students
for (int i = 0; i < 100; i++) {
    printf("Student %d: %s (GPA: %.2f)\n", 
           students[i].id, 
           students[i].name, 
           students[i].gpa);
}
```

### 2.8 Pointers to Structures

You can use pointers with structures:

```c
struct Student s1 = {12345, "Alice", 3.75};
struct Student *ptr = &s1;

// Method 1: Using (*ptr).member
printf("ID: %d\n", (*ptr).id);

// Method 2: Using ptr->member (preferred)
printf("ID: %d\n", ptr->id);
printf("Name: %s\n", ptr->name);
printf("GPA: %.2f\n", ptr->gpa);
```

**The Arrow Operator (`->`):**
- `ptr->member` is equivalent to `(*ptr).member`
- Much cleaner and more readable
- Commonly used when passing structures to functions

### 2.9 Structures and Functions

**Passing by Value:**
```c
void printStudent(struct Student s) {
    printf("ID: %d\n", s.id);
    printf("Name: %s\n", s.name);
    printf("GPA: %.2f\n", s.gpa);
}

// Usage
struct Student s1 = {12345, "Alice", 3.75};
printStudent(s1);  // Entire structure is copied
```

**Passing by Reference (Pointer):**
```c
void updateGPA(struct Student *s, float newGPA) {
    s->gpa = newGPA;
}

// Usage
struct Student s1 = {12345, "Alice", 3.75};
updateGPA(&s1, 3.85);  // Pass address of structure
printf("Updated GPA: %.2f\n", s1.gpa);  // Output: 3.85
```

**Returning Structures from Functions:**
```c
struct Student createStudent(int id, char *name, float gpa) {
    struct Student s;
    s.id = id;
    strcpy(s.name, name);
    s.gpa = gpa;
    return s;
}

// Usage
struct Student s1 = createStudent(12345, "Alice", 3.75);
```

### 2.10 Practical Example: Student Database

```c
#include <stdio.h>
#include <string.h>

struct Student {
    int id;
    char name[50];
    float gpa;
    int age;
};

// Function to input student data
void inputStudent(struct Student *s) {
    printf("Enter Student ID: ");
    scanf("%d", &s->id);
    
    printf("Enter Student Name: ");
    scanf(" %[^\n]", s->name);
    
    printf("Enter Student GPA: ");
    scanf("%f", &s->gpa);
    
    printf("Enter Student Age: ");
    scanf("%d", &s->age);
}

// Function to display student data
void displayStudent(struct Student s) {
    printf("\n--- Student Information ---\n");
    printf("ID: %d\n", s.id);
    printf("Name: %s\n", s.name);
    printf("GPA: %.2f\n", s.gpa);
    printf("Age: %d\n", s.age);
}

int main() {
    struct Student students[3];
    
    // Input data for 3 students
    for (int i = 0; i < 3; i++) {
        printf("\nEnter details for student %d:\n", i + 1);
        inputStudent(&students[i]);
    }
    
    // Display all students
    printf("\n\n=== All Students ===\n");
    for (int i = 0; i < 3; i++) {
        displayStudent(students[i]);
    }
    
    return 0;
}
```