Introduction


Arrays are powerful features of any programming language, An array is a fundamental data structure that allows you to store a fixed-size, sequential collection of elements of the same type. Rather than declaring multiple individual variables to hold related data. such as score1, score2, score3 you declare a single array variable and use indexes to manage the collection.

An array is a way of keeping track of a list or collection of many related things altogether. Imagine, for instance, that you have a high score board in a game with up to 20 high scores on it. Using what we know, you could easily create one variable for every score you want to keep track of. Something like this:

int score1 = 100;
int score2 = 95;
int score3 = 92;
// ...

That’s one way to do it. But what if you had 10,000 scores? Suddenly, creating that many variables to store scores is overwhelming.

This brings us to arrays. Arrays are perfect for keeping track of things like this since they could store 20 scores or 10,000 scores in a way that is both easy to create and easy to work with once they’re created.

Core concepts

  • fixed size: once an array is initialized, it’s capacity is set you cannot increase or decreases the number of slots int he array without creating a new one.
  • Homogeneous elements: Every item stored int he array must be of the same data type
  • zero-based indexing: C# uses a zero based numbering system. the first element in an array is accessed at index 0, the second at index 1, and the last element at index (length -1)
  • Reference Type: in C#, arrays are objects stored on the heap. Theis makes them more efficient for memory management when dealing with large datasets.

Declaring and initializing arrays in C#


Creating an array is similar to creating a standard variable, but with specific syntax to handle multiple items. This process involves declaration, instantiation ( using the new keyword), and initialization.

1.Declaration and Instantiation To create an array, you use square brackets [] after the data type. To actually “build” the array in memory, you must use the new keyword and specify the size.

// Declaration: Tells the computer "scores" will hold an array of integers
int[] scores;

// Instantiation: Creates an array that can hold exactly 10 integers
scores = new int[10];


// Shorthand: Doing both on one line
int[] scores = new int[10];

2.Accessing Elements (indexing) to access a specific item (an element) in array you use an index inside square brackets crucial Rule: C# arrays are 0-based

  • The 1st item is at index 0
  • The 2nd item is at index 1
  • The 10th item is at index 9
int[] scores = new int[10];

// Setting values (Assigning)
scores[0] = 100; // First element
scores[1] = 95;  // Second element
scores[9] = 10;  // Last element

// Getting values (Accessing)
int firstScore = scores[0];
int secondScore = scores[1];  //todo, add print statements. to show the values. 

Warning: Off-by-One Errors if you create an array of size 10 and try to access scores[10] your program will crash with anIndexOutOfRangeException. This is because the highest index for a size of 10 is actually 9.

3.Alternative Initialization method C# provides “syntax sugar” to make creating arrays faster if you already know what data should go inside them.

The curly brace method you can provide the values immediately using curly braces {} The compiler will automatically count the item for you.

// Method A: Explicit size and values
int[] scores = new int[5] { 100, 95, 92, 87, 55 };

// Method B: Let the compiler count the size (Recommended)
int[] scores = new int[] { 100, 95, 92, 87, 55 };

// Method C: The ultra-short version => new int[5] {100, 95,92,87,55}
int[] scores = { 100, 95, 92, 87, 55 };

4.The Length Property Once an array is created, you often need to known how many items it hold (especially when using loops). You can find this using the .Length property.

int[] scores = { 100, 95, 92, 87, 55, 50 };

int totalElements = scores.Length;

Console.WriteLine("The array holds " + totalElements + " scores.");
// Output: The array holds 6 scores.
TermDefinitionExample
TypeThe kind of data in the arrayint[] or string[]
ElementAn individual item in the arrayscores[0]
IndexThe address or position of an element0, 1, 2...
LengthThe total number of items in the arrayscores.Length

Examples


Example-1: finding the minimum value This is like looking through a deck of cards to find the lowest number. You keep the lowest card you’re seen so far in your hand, and every time you pick up a new card, you compare it to the one in your hand.

int[] array = { 4, 51, -7, 13, -99, 15, -8, 45, 90 };

// We start with the largest possible integer so that 
// the first number we check is guaranteed to be smaller.
int currentMinimum = Int32.MaxValue; 

for (int index = 0; index < array.Length; index++)
{
    // Check: Is the number we are looking at smaller than our current record?
    if (array[index] < currentMinimum)
    {
        // Update the record with the new smallest number
        currentMinimum = array[index];
    }
}

Console.WriteLine("The smallest number is: " + currentMinimum);

Why use Int32.MaxValue? If you started currentMinimum at 0 and your array only contained positive numbers like {10, 20, 30}, your program would wrongly say 0 is the minimum. By starting at the highest possible value, any number in your array will successfully “beat” it on the first check.

Example-2: Calculating the Average Value To find an average, you need two things: the Sum (everything added together) and the Count (how many items there are).

int[] array = { 4, 51, -7, 13, -99, 15, -8, 45, 90 };
int total = 0;

for (int index = 0; index < array.Length; index++)
{
    // Add the current element to our running total
    total += array[index];
}

// Calculate the average. 
// We use (float) to make sure the math allows for decimals (e.g., 10.5 instead of 10).
float average = (float)total / array.Length;

Console.WriteLine("The total sum is: " + total);
Console.WriteLine("The average is: " + average);

The Importance of (float): In C#, if you divide an integer by an integer (like 10 / 4), it will give you 2 because it throws away the remainder. By “casting” the total to a float, you tell C# to perform decimal division, giving you the accurate answer of 2.5.

Arrays of Arrays and Multi-dimensional Arrays


understanding how data stacks up in “grids” is a huge milestone in programming. Whether you’re building a game map, a spreadsheet, or a seating chart, you’ll like use either Jagged Arrays or multi-Dimensional Arrays

1. Arrays of Arrays (jagged Array) int[][]

Think of a Jagged Array like a bookshelf where every shelf can be a different length. Technically, it is an array where each “slot” contains another, independent array. This is an array of pointers Each “row” is actually a separate object located in different part of the computer’s memory.

  • The computer’s view: It looks at the first array to find a “folder”, then goes to a completely different memory address to find the actual data in the folder.
  • Flexibility: This is why rows can be different lengths each row is its own independent array.
int[][] jagged = new int[3][];
jagged[0] = new int[] { 1, 2, 3 };
jagged[1] = new int[] { 4, 5 };
jagged[2] = new int[] { 6, 7, 8, 9 };

// Outer loop: Travels down the rows
for (int i = 0; i < jagged.Length; i++) 
{
    // Inner loop: Travels across the columns of THIS specific row
    for (int j = 0; j < jagged[i].Length; j++) 
    {
        Console.Write(jagged[i][j] + " ");
    }
    Console.WriteLine(); // Move to the next line after each row
}

Because each row can be a different length, we use jaggedArray.Length for the rows, and jaggedArray[i].Length for each specific row.

This is Non-Contiguous Memory. It is a “Hierarchy of Arrays.” The main array doesn’t hold numbers; it holds addresses (pointers) to where the actual data lives.

Memory Layout

Master Array (The "Map")
Address:   0xA1        0xA2
         +-----------+-----------+
Data:    | PTR to R0 | PTR to R1 |  (PTR = Memory Address)
         +-----------+-----------+
               |           |
               |           +---------------------->  Row 1 (Somewhere else in RAM)
               |                                     Address: 0xC1  0xC2
               v                                            +-----+-----+
             Row 0 (Somewhere in RAM)                Data:  | 40  | 50  |
             Address: 0xB1  0xB2  0xB3                      +-----+-----+
                    +-----+-----+-----+
             Data:  | 10  | 20  | 30  |
                    +-----+-----+-----+
  • Pros: Each row can be a different size (as seen above, Row 0 has 3 items, Row 1 has 2).

  • Cons: Slightly slower because the CPU has to look at the “Map” first, get an address, and then “jump” to a completely different part of memory to find the number.

2.Multi-Dimensional Arrays (Rectangular) int[,]

A Multi-Dimensional Array is like a perfect grid or a printed Excel sheet. Once you define the dimensions (Rows × Columns), every row must be the same length. This is a single, solid block of memory. When you declare new int[3, 3], the computer sets aside space for exactly 9 integers all in one row.

  • The computer’s view: It sees one long line of number and just does some quick math to find the right “square”

  • Performance: usually faster to access because everything is grouped together.

  • Key Feature: It’s a single “block” of memory. It’s cleaner and often easier to read if you know your grid will stay the same size.

  • Best for: Coordinate systems, game boards (Chess), or mathematical matrices.

// Create a 4x4 grid (16 slots total)
int[,] matrix = new int[4, 4];

// Assign values using a single set of brackets
matrix[0, 0] = 1; // Top-left corner
matrix[0, 3] = 5; // Top-right corner
matrix[3, 3] = 1; // Bottom-right corner
int[,] matrix = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};

// GetLength(0) is the first dimension (Rows)
for (int row = 0; row < matrix.GetLength(0); row++) 
{
    // GetLength(1) is the second dimension (Columns)
    for (int col = 0; col < matrix.GetLength(1); col++) 
    {
        Console.Write(matrix[row, col] + "\t");
    }
    Console.WriteLine();
}

Since this is a solid block, we use .GetLength(0) for rows and .GetLength(1) for columns.

This is a contiguous Memory The computer calculates the position of an element using a formula because every row is exactly the same size. It is one solid block

Memory Layout

Address:   0x01  0x02  0x03  0x04  0x05  0x06
         +-----+-----+-----+-----+-----+-----+
Data:    | 10  | 20  | 30  | 40  | 50  | 60  |
         +-----+-----+-----+-----+-----+-----+
           \_______Row 0_______/ \_______Row 1_______/

Pros: Very fast. The CPU can “predict” where the next number is. Access: To find [1, 0], the computer just jumps ahead by the length of one row.

The Foreach Loop


The Foreach loop is the most elegant and readable way to iterate through collections in C#. It is specifically designed for when you want to read every item in a list or array without worrying about the math of indices.

1.The foreach loop Think of foreach as telling the computer: “Go through this pile of items, one by one, and let me do something with each one until the pile is empty.”

int[] scores = { 95, 82, 100, 67 };

foreach (int score in scores)
{
    // 'score' represents the CURRENT item the loop is holding
    Console.WriteLine("Found a score: " + score);
}

Why use it?

  • Safety: You cannot go “out of bounds.” The loop starts at the beginning and stops exactly at the end.
  • Readability: The code looks like plain English.
  • Cleanliness: You don’t have to manage a counter variable like i++.

2. foreach vs for when to use which? while foreach is simpler, it has two major limitations that might force you to use a standard for loop.

Limitation A: The “Blind” loop (no index) In a foreach loop, the computer doesn’t tell you where you are. You know you have a “score”, but you don’t know if it’s the 1st sore or the 10th score

Loop TypeKnowing the PositionExample Use Case
foreachNo IndexPrinting all names in a list.
forHas indexUpdating only the even-numbered seats in a theater.

Limitation B: Read-Only Access In C#, the variable in a foreach loop is read-only. You cannot use it to change the value inside the original array.

// THIS WILL FAIL
foreach (int score in scores) {
    score = score + 5; // Error! You can't modify the collection here.
}

// THIS WORKS
for (int i = 0; i < scores.Length; i++) {
    scores[i] = scores[i] + 5; // Success! You are targeting the memory slot directly.
}

foreach with Multi-dimensional Array

using a foreach loop with a multi-dimensional Array ([,]) is a bit like magic in C#. While it looks like a grid to us, foreach treats it like one long, continuous line of data.

When you use foreach on a 2D array, it starts at the top-left corner [0, 0] and reads across the row. When it hits the end of that row, it automatically jumps to the start of the next row.

int[,] matrix = {
    { 10, 20 },
    { 30, 40 },
    { 50, 60 }
};

// Even though it's 2D, we only need ONE variable in foreach
foreach (int value in matrix)
{
    Console.WriteLine(value);
}

output

10
20
30
40
50
60