Arrays

Arrays

Introduction to Data Structures

  • Data structures is a composite of related data items stored under the same name.
  • Data structures allows programmers to store data in a more organized fashion.

Definition of Arrays

  • Array: A collection of data items of the same type.
  • Array Element: A data item that is part of an array.
  • An array consists of two or more adjacent memory cells, e.g., 4, 2, 46, 3, 8, 55, 3, -9, 4, 5, where each element corresponds to an index.

Declaring an Array in C

  • An array requires:
    • Type of values stored in the array.
    • Identifier (name of the array).
    • Number of elements in the array.
    • Example:
      int x[8]; // Declares an array of 8 integers

Stack Space Visualization of Arrays

  • Arrays are stored in adjacent memory cells.
  • Example array int x[8]; initializes 8 adjacent cells in stack space,
  • Visualization of stack space:
    • AA9, AA8, AA7, AA6, AA5, AA4, AA3, AA2, AA1, AA0 are memory addresses of stack space occupied by array.
  • Live demo is suggested to visualize the concept.

Addresses in Memory

  • Addresses of array elements are displayed in hexadecimal format:
    • Example: int arr[8];
    • &arr[0] is 0x7ffd87d323c0
    • &arr[1] is 0x7ffd87d323c4
    • Addresses increase by 4 bytes for int types since they hold 4 bytes.
  • Conclusion: The size of respective data types in memory is critical for understanding addresses:
    • int: 4 bytes
    • double: 8 bytes
    • float: 4 bytes
    • char: 1 byte

Interesting Facts about Array Variables

  • The address of the array variable (&arr) is the same as the address of the first element (&arr[0]).
  • This indicates that the array variable is stored in memory at the address of its first element.

Accessing Values Stored in Adjacent Memory Cells

  • Accessing values is done through subscripting, e.g., x[0], x[1], etc.
  • Code snippet demonstrating access:
    arr[4] // Accesses the fifth element of the array
  • Visualization of how memory values change as elements are accessed:
    • Each access modifies values as shown through a step-by-step process of assigning elements.

Useful Statements to Access/Manipulate Arrays

  • Important statements:
    • printf(“%d”, x[0]); // Displays the value stored at x[0]
    • x[3] = 1; // Stores the value 1 in x[3]
    • sum = x[0] + x[1]; // Stores sum of x[0] and x[1]
    • sum += x[2]; // Adds x[2] to sum.
    • x[3] += 13; // Adds 13 to x[3].
    • x[2] = x[0] + x[1]; // Assigns the sum of x[0] and x[1] to x[2].

Array Initialization

  • Arrays must be declared and initialized explicitly.
  • A declaration requires specifying data type and size.
  • Arrays can be declared and initialized in one line without specifying size.
  • Uninitialized arrays contain garbage values.
  • Example code to illustrate initialization:
    int arr[5]; // Declares an array of 5 integers
  • Output will show random garbage values for uninitialized elements.

Special Syntax for Initialization List

  • C allows initialization through a syntax that eliminates garbage values:
    int arr[] = {2, 4, 6, 8, 10}; // Declaration and initialization in one line
  • This method pre-fills default values eliminating garbage values.
  • C calculates array size from the number of initializer values automatically without providing a size.
  • Code example to illustrate this:
    for (int x = 0; x < 5; ++x) { printf("arr[%d] = %d\n", x, arr[x]); }

Default Values for Data Types

  • For uninitialized arrays:
    • int: 0
    • double: 0.0
    • float: 0.0
    • char: '\0' (Null character)
    • pointer: Null

Variable Length Arrays (VLAs)

  • VLAs use static memory, meaning sizes cannot be altered at runtime.
  • It is a bad practice to use variables to declare array sizes due to potential segmentation faults (attempting large inputs can crash program).
  • Example of bad declaration:
    int size; scanf("%d", &size); int arr[size]; // Not recommended

Subscript Operations on Arrays

  • Subscripting is key for accessing and modifying array elements.
  • Examples of assignments and allowable operations:
    x[i - 1] = x[i]; // Move value from current index to previous index x[i] = x[i + 1]; // Shifts value from next index to current
  • Invalid operation example:
    x[i] - 1 = x[i]; // Illegal operation

sizeof() Operator

  • sizeof() is crucial for determining the size of data types, helpful in identifying the number of elements in an array.
  • For example:
    int arr[10]; // Array of 10 integers int num1 = sizeof(arr); // Total size in bytes int num2 = sizeof(arr[0]); // Size of one element
  • Breakdown:
    • If an int is 4 bytes and an array of 10 integers is defined, size returns 40 bytes.
    • Thus, dividing the total size by the size of an int gives the number of elements: \frac{40}{4}=10.

Using Loops to Access Arrays

  • Loops facilitate access across all elements of an array efficiently, iterating through indices.

Passing Arrays to Functions

  • Arrays can be passed to functions similar to variables. When passed, they are passed by reference (pointer access).
  • Example of a function taking an array as parameter:
    void fillArray(int list[], int val) { for (int i = 0; i < SIZE; ++i) list[i] = val; }
  • This is more efficient as only 8 bytes (pointer size) are passed rather than the array elements themselves, which can be significantly larger.

Limitations and Overview

  • It is essential to track the size of arrays passed to functions, as sizeof(arr) in functions only provides the size of a pointer, not of the actual array elements.
  • Users are encouraged to define a size parameter explicitly when dealing with arrays in user-defined functions.
  • Conclusion on usability and risks regarding array definitions, manipulations, and memory management in C programming, emphasizing safe and efficient programming practices with arrays.