# 4.4 Pointers and Data Files

### 1. **Pointers**

1. **What is a Pointer?**
   * A pointer is a variable that stores the *memory address* of another variable.
   * Syntax:

     ```c
     int a = 10;
     int *p = &a;  // 'p' is a pointer to 'a', storing its address.
     printf("%d", *p); // Dereference 'p' to access the value of 'a': 10
     ```
2. **Pointer Arithmetic**
   * You can perform arithmetic operations on pointers to navigate through memory locations.
   * Valid operations:
     * **Increment (`p++`)**: Moves to the next memory location of the same type.
     * **Decrement (`p--`)**: Moves to the previous memory location.
     * **Addition/Subtraction (`p + n`, `p - n`)**: Adjusts the pointer by `n` locations.
   * Example:

     ```c
     int arr[] = {10, 20, 30};
     int *p = arr;     // Points to the first element of 'arr'.
     printf("%d\n", *p);  // Output: 10
     p++;               // Move pointer to the next element.
     printf("%d\n", *p);  // Output: 20
     ```
3. **Passing Pointers to Functions**
   * Pointers allow functions to modify the original value of variables.
   * Example:

     ```c
     void increment(int *n) {
         (*n)++; // Increment the value pointed to by 'n'
     }

     int main() {
         int num = 5;
         increment(&num);  // Pass the address of 'num'.
         printf("%d", num);  // Output: 6
         return 0;
     }
     ```

***

### 2. **Structures**

1. **What is a Structure?**
   * A structure is a user-defined data type that groups variables of different types under a single name.
   * Syntax:

     ```c
     struct Student {
         int id;
         char name[50];
     };
     ```
   * **Declaration**:

     ```c
     struct Student s1;
     s1.id = 101;
     strcpy(s1.name, "Alice"); // Assign string to 'name'
     printf("ID: %d, Name: %s\n", s1.id, s1.name);  // Output: ID: 101, Name: Alice
     ```
2. **Pointer to a Structure**
   * Accessing structure members using a pointer:

     ```c
     struct Student s1 = {101, "Alice"};
     struct Student *ptr = &s1;
     printf("ID: %d, Name: %s\n", ptr->id, ptr->name);  // Output: ID: 101, Name: Alice
     ```
3. **Array of Structures**
   * Example:

     ```c
     struct Student {
         int id;
         char name[50];
     };

     struct Student students[2] = {{101, "Alice"}, {102, "Bob"}};
     printf("Student 1: %s\n", students[0].name);  // Output: Student 1: Alice
     printf("Student 2: %s\n", students[1].name);  // Output: Student 2: Bob
     ```

***

### 3. **Unions**

1. **What is a Union?**
   * A union is similar to a structure but uses shared memory for all its members. Only one member can hold a value at any given time.
   * Syntax:

     ```c
     union Data {
         int i;
         float f;
     };

     union Data d;
     d.i = 5;
     printf("%d\n", d.i);  // Output: 5
     d.f = 3.14;
     printf("%f\n", d.f);  // Output: 3.140000
     ```
2. **Key Difference from Structures**
   * **Structure**: Allocates memory for all members.
   * **Union**: Allocates memory for the largest member only.

***

### 4. **File Operations**

1. **File Modes**
   * `"r"`: Open a file for reading.
   * `"w"`: Open a file for writing (overwrites if the file exists).
   * `"a"`: Open a file for appending (writes at the end without overwriting).
2. **Basic File Handling Functions**
   * **`fopen()`**: Opens a file.
   * **`fclose()`**: Closes a file.
   * **`fprintf()` and `fscanf()`**: Handles formatted input/output.
   * **`fread()` and `fwrite()`**: Handles binary data.
3. **Examples**
   * **Writing to a File**:

     ```c
     include <stdio.h>
     int main() {
         FILE *file = fopen("data.txt", "w");  // Open file in write mode
         if (file == NULL) {
             printf("Error opening file!\n");
             return 1;
         }
         fprintf(file, "Hello, World!\n");  // Write to file
         fclose(file);  // Close file
         return 0;
     }
     ```
   * **Reading from a File**:

     ```c
     #include <stdio.h>
     int main() {
         FILE *file = fopen("data.txt", "r");  // Open file in read mode
         char str[100];
         if (file == NULL) {
             printf("File not found!\n");
             return 1;
         }
         while (fscanf(file, "%s", str) != EOF) {  // Read words until EOF
             printf("%s\n", str);  // Print each word
         }
         fclose(file);  // Close file
         return 0;
     }
     ```
   * **Binary File Handling**:

     ```c
     #include <stdio.h>
     struct Student {
         int id;
         char name[50];
     };

     int main() {
         FILE *file = fopen("student.dat", "wb");  // Open binary file for writing
         struct Student s = {101, "Alice"};
         fwrite(&s, sizeof(s), 1, file);  // Write structure to file
         fclose(file);  // Close file

         file = fopen("student.dat", "rb");  // Open binary file for reading
         struct Student readStudent;
         fread(&readStudent, sizeof(readStudent), 1, file);  // Read structure
         printf("ID: %d, Name: %s\n", readStudent.id, readStudent.name);  // Output: ID: 101, Name: Alice
         fclose(file);  // Close file
         return 0;
     }
     ```
4. **Common File Handling Errors**
   * Forgetting to close a file.
   * Trying to read a file that doesn’t exist.
   * Using the wrong file mode.

### Conclusion

* Pointers, structures, unions, and file operations are essential concepts in C programming. Pointers provide direct memory manipulation and efficient data handling.
* Structures enable grouping of related data, while unions optimize memory usage by sharing storage among members.
* File operations facilitate data persistence and management through various modes and functions.
