Day 76: Address Values of Multi-D Arrays

I further worked on multi-dimensional arrays in C. I got super confused because I thought that a two-dimensional array was made up of pointers to the two array elements. That seems to not really be the case. Or at least that’s what my test code seems to be indicating. I still need some more clarity but I am making progress. I hear once you have used pointers in 100 different lines of code you evolve into a higher life for XD… Wouldn’t that be something.

TLDR;

Okay, so here are the highlights of what I did:

  • Continued to work on the “Technical Questions” section of the book “Cracking the Coding Interview” by Gayle Laakmann McDowell. Within that, I continued my work on Tree data structures. Started trying to replicate the example pretty print functions provided in the article I am reading through. I continued making progress testing the values of addresses and increments in my two-dimensional array. I think the address of the first element in the second array is stored as the address of the second array as opposed to a pointer. I don’t even know if that made sense. Check my notes. It will help, I think.
  • Reviewed some more Git commands. Specifically working with remote repositories. I am currently trying to bypass the password prompt on a remote machine used to run commands automatically. I am not sure if ssh keys are the way to go. I need to do more reading to better understand what I’m doing. I’m clueless right now. Just breaking things and seeing what happens.

Working with Multidimensional Arrays Notes

To start we must be aware that when dealing with multidimensional arrays there is no longer any duality between pointers and the array binding/variable themselves. A duality did exist between one-dimensional arrays and pointers (meaning the array binding/variable and a pointer to that array were interchangeable… They both pointed to the first element in the array by default – I think).

For example, a two-dimensional array is stored in a single continuous block of memory. Rather than view this block of memory as a two-dimensional array it is more appropriate to think of it as a one-dimensional array where the value being stored at each element is itself an array. For example, let’s say we have a two-dimensional array of integers. Just like with a one-dimensional array, the array binding/variable automatically points to the memory address for the first element in the array. The difference here is, the element itself is another array. So that address points to the first element in that array.

# include <stdio.h>
# include <stdlib.h>

int main(){

  int singleArr[3] = {2, 3, 6};
  int doubleArr[][3] = { {2, 3, 6}, {4, 5, 8} };

  printf("single array address 1: %d\t\t value 1: %d\n", singleArr, *singleArr);
  printf("double array address 1: %d\t\t value 1: %d\n", (*doubleArr), *(*doubleArr));


  return 0;
}
# Output:

single array address 1: 6422308		 value 1: 2
double array address 1: 6422284		 value 1: 2

The singleArr binding automatically points to the address of the first element in the array. It only needs to be dereferenced once to get the value stored in at that address since it already points to it. This gives us *singleArr = 2

The doubleArr binding automatically points to the address of the first element in the array but that element is an array itself. To access the value of that array instead of the address we must dereference the pointer once. Once it has been dereferenced we get a pointer to the first element of the array that is itself the first element of the doubleArr array. To get the value of this element which corresponds to the common arr[0][0] notation we would once again dereference the pointer. This gives us *(*doubleArr) = 2

So now what if we want to access the second element in the one-dimensional array and the second element in the two-dimensional array. Well we would get an integer in the one-dimensional array and another array in the two-dimensional array. So we would actually want the first element of the array which is itself the second element in the array of arrays (a.k.a. the two-dimensional array).

/*
 * The goal for this program is to print all the addresses and all the values of the two-dimensional array. By looping through the doubleArr binding.
 * */
# include <stdio.h>
# include <stdlib.h>

int main(){

  int singleArr[3] = {2, 3, 6};
  int doubleArr[][3] = { {2, 3, 6}, {4, 5, 8} };

  printf("int singleArr[3] = {2, 3, 6}\n");
  printf("int doubleArr[][3] = { {2, 3, 6}, {4, 5, 8} }\n");

  printf("single array address 1: %d\t\t value 1: %d\n", singleArr, *singleArr);
  printf("double array address 1: %d\t\t value 1: %d\n", (*doubleArr), *(*doubleArr));

  printf("\n--------------------\n");
  printf("doubleArr address 1: %d\n", doubleArr);
  printf("doubleArr address 2: %d\n", doubleArr+1);
  printf("doubleArr value @ address 1: %d\n", *doubleArr);
  printf("doubleArr value @ address 2: %d\n", *(doubleArr+1));
  printf("\n--------------------\n");

  printf("single array address 2: %d\t\t value 2: %d\n", singleArr+1, *(singleArr+1));
  printf("double array address 2: %d\t\t value 2: %d\t\taddress 1: %d\t\t value 1: %d\n", (doubleArr+1), (*(doubleArr+1)), (*(doubleArr+1)), (*(*(doubleArr+1))));

  return 0;
}
# Output:

int singleArr[3] = {2, 3, 6}
int doubleArr[][3] = { {2, 3, 6}, {4, 5, 8} }
single array address 1: 6422308		 value 1: 2
double array address 1: 6422284		 value 1: 2

--------------------
doubleArr address 1: 6422284
doubleArr address 2: 6422296
doubleArr value @ address 1: 6422284
doubleArr value @ address 2: 6422296

--------------------
single array address 2: 6422312		 value 2: 3
double array address 2: 6422296		 value 2: 6422296		address 1: 6422296		 value 1: 4

Conclusion

That’s all for today. This is my sixth round of the “#100daysofcode” challenge. I will be continuing my work from round five into round six. I am currently working through the book “Cracking the Coding Interview” by Gayle Laakmann McDowell. My goal is to become more familiar with algorithms and data structures. This goal was derived from my goal to better understand operating systems and key programs that I use in the terminal regularly e.g. Git. This goal was in term derived from my desire to better understand the fundamental tools used for coding outside of popular GUIs. This in turn was derived from my desire to be a better back-end developer.

I have no idea if my path is correct but I am walking down this road anyways. Worst case scenario I learn a whole bunch of stuff that will help me out on my own personal projects.