Two-Dimensional Arrays in C

Arrays can be initialized on their declaration. This initialization takes place when the program is loaded.  The list of initializers should be enclosed in curly braces, and each element must be separated by commas.

#include <stdio.h>


int main(void){
    
    int i;
    
    short smallNums[] = {1, 5, 11, 13, 17, 23};
    int largerNums[7] = {42, 47, 73, 404, 808, 2600, 40000};    
    //shorthand for string array
    char aString[] = "I can't do that, Dave.";
    
    printf("%s\n", aString);
    
    
    //use sizeof() to get array size
    for(i = 0; i < sizeof(smallNums)/sizeof(smallNums[0]); i++){
            printf("%d\t", smallNums[i]);
    }
    
    return 0;
}

Note that if no size of the array is given when initializing the array, the bound is taken to be the number of initializers.

Two-dimensional arrays are often called rectangular arrays, as their structure resembles that of a two-dimensional grid such as seen on a spreadsheet.

#include <stdio.h>


int main(void){
    
    //number of horizontal rows
    const int Row_Size = 10;
    //number of vertical columns
    const int Column_Size = 5;
    
    int twoDimArray[Row_Size][Column_Size];
    
    //sizeof() returns unsigned long
    printf("Size of twoDimArray = %lu\n", sizeof(twoDimArray));
    
    int size = Row_Size * Column_Size * sizeof(int);
    
    printf("Size of twoDimArray = %d\n", size);
    
    printf("Size of one row in twoDimArray = %lu\n", sizeof(twoDimArray[0]));
    
    size = Column_Size * sizeof(int);
    
    printf("Size of one row in twoDimArray = %d\n", size);
    
    return 0;
}

Note that the elements in a two-dimensional array are stored in row-major order, meaning that each row forms an array of elements in memory. Technically speaking, each row is itself a one-dimensional array, and can be used as such.

#include <stdio.h>


int main(void){
    
    int intArray[3][5];
    
    int i, j;
    
    //use nested for loop
    //to assign values to each
    //array element
    for(i = 0; i < 3; i++){
        for(j = 0; j < 5; j++){
            intArray[i][j] = 1 + i + j;    
        }
    }
    
    //print out last row of array
    for(i = 0; i < 5; i++){
        printf("%d\t", intArray[2][i]);
    }
    
    return 0;
}

We can use arrays to recreate the famous Towers of Hanoi puzzle. In this puzzle there are three vertical pegs onto which are placed disks of varying sizes. At the start of the puzzle, all of the disks are placed in hierarchical order from largest to smallest on the leftmost peg. We can move a disk onto another peg only if every disk on that peg is larger than it. The goal is to move all of the disks to the rightmost peg.

This puzzle is typically used in computer science courses as a visual aid to thinking of how the stack data structure works. Each stack of disks is like a programming stack, since items can only be removed or added to the top of the stack.

#include <stdio.h>

const int num_disks = 3;

int pop(int i, int pegs[3][num_disks], int numDisks[]);
void push(int i, int disk, int pegs[3][num_disks], int numDisks[]);
void dumpPegs(int pegs[3][num_disks], int numDisks[]);
void moveDisk(int source, int destination, int pegs[3][num_disks], int numDisks[]);

int main(void){
    
    int pegs[3][num_disks] = {0};

    //number of disks on each peg
    int numDisks[3] = {0};
    
    push(0, 3, pegs, numDisks);
    push(0, 2, pegs, numDisks);
    push(0, 1, pegs, numDisks);
    
    dumpPegs(pegs, numDisks);
    
    moveDisk(0, 2, pegs, numDisks);
    
    dumpPegs(pegs, numDisks);
    
    moveDisk(0, 1, pegs, numDisks);
    
    dumpPegs(pegs, numDisks);
    
    moveDisk(2, 1, pegs, numDisks);
    
    dumpPegs(pegs, numDisks);
    
    moveDisk(0, 2, pegs, numDisks);
    
    dumpPegs(pegs, numDisks);
    
    moveDisk(1, 0, pegs, numDisks);
    
    dumpPegs(pegs, numDisks);
    
    moveDisk(1, 2, pegs, numDisks);
    
    dumpPegs(pegs, numDisks);
    
    moveDisk(0, 2, pegs, numDisks);
    
    dumpPegs(pegs, numDisks);
    
    return 0;
}


void moveDisk(int source, int destination, int pegs[3][num_disks], int numDisks[]){
    int disk = pop(source, pegs, numDisks);
    push(destination, disk, pegs, numDisks);
}

void push(int i, int disk, int pegs[3][num_disks], int numDisks[]){
    if(i >= 0 && i <= 2){
        pegs[i][numDisks[i]++] = disk;
    }
}

int pop(int i, int pegs[3][num_disks], int numDisks[]){
    if(i >= 0 && i <= 2){
        if(numDisks[i] >= 1){
            return (pegs[i][--numDisks[i]]);
        }
    }
    return -1;
}

void dumpPegs(int pegs[3][num_disks], int numDisks[]){
    int i,j;
    
    for(i = 0; i < 3; i++){
        for(j = 0; j < num_disks; j++){
            if(j < numDisks[i]){
                printf("%d", pegs[i][j]);
            } else {
                putchar(' ');
            }
        }
        putchar('\t');
    }
    putchar('\n');
}

This example above provides a brute-force solution to the puzzle if there are three disks. But what if there are four disks? Or five? In that case, we should use a recursive function. But that is for another time.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s