FANDOM


OverviewEdit

In this lesson you will learn about a large selection of more advanced topics including memory addresses, pointers, and basic object oriented programming.

MemoryEdit

Now that you have a solid foundation in C++ programming. I can now explain to you a very important topic that will be with forever. It is the concept of memory locations. In this case I mean location in RAM (random access memory). Every variable you define is given some place in memory. For example, I could define an integer i which is a 4 byte variable and it might be given a location like 0xbf9c9e7c. I am not going to go into how this is chosen because it is a LONG story. So, to keep things short just know that independent variables are pretty much chosen randomly. Therefore there is no way to predict what their address will be. Also a variables address is a constant so it CANNOT BE CHANGED

Arrays Edit

Arrays have a very useful property in their memory allocation. It is that all array elements are placed right after each other in memory. That is why you must define a length for the array at declaration. This gives us some unique properties which I will get into later.

Address and Dereference OperatorsEdit

There are two more and probably the last ones I will show you: & and *. From left to right: Address and Dereference(not multiplication) operators. The Address operator gives you the address of a variable and the dereference operator will give you the value of the variable at a given address. These have countless uses but I will show an introductory one: 


#include<iostream>
using namespace std;

void swap(int &a, int &b);

int main()
{
  int a=5, b=3;
  swap(a,b);
  cout<< a << "  " << b;
  return 0;
}

void swap(int &a, int &b)
{
   int temp=a;
   a=b,b=temp;
}

In this case I just used the Address operator to create a swap function. This function is very relevant because it is an example of how a function can change the actual values of the variables going into it. In this case, I just swapped the two values but, as with most other topics, it can be used however you want.

PointersEdit

Building on those fundamental concepts about memory, it is essential to talk about an abstract data type known as a pointer. Before I start, I recommend that you read this short pdf on the topic. That pdf was written by the professor who taught this to me. It gets at most of the basic ideas. Effectively, the pointer is a variable that holds the memory location of another variable. They will be immensely helpful as we move on because they are used in every data structure that I will show to you. Here are some important ideas when it comes to pointers:

Modifying the the address vs. modifying the value at the addressEdit

This is the most important skill you need to have when using pointers. To change addresses of pointers you can assign the memory addresses directly to them like you do for normal variable although I do not recommend trying to assign a constant value 0x5e8f9a5c. I would do an assignment like:

int i=0;
int *p=&i;

As you can see, the assignment is very simple. To contrast, here is an example of changing the value stored at the pointer:

int i=0;
int *p=&i;
*p=1;
cout<< i:

As you see in this example, the value at i was changed. This is obviously a very important property of pointers that you will use often. These are the only two things that you will do with pointers and from here it is just a combination of getting a feel for them and learning their applications.

Arrays (revisited) and pointer arithmeticEdit

Now that we know what pointers are, I can explain what arrays really are. Arrays are constant pointers with reserved space that comes after them. They point to the location that is at the beginning of the allotted space. They operate under a principle of something called pointer arithmetic. Basically it is that if you have a pointer, p, that points to a memory location that has b bytes and a integer, i, then p+i will point to the memory location that is b*i bytes in front of it. That may be a bit much to digest at first but look at this example:


#include<iostream>
using namespace std;

int main()
{
  int a[5]={0,1,2,3,4};
  cout<< a << " -> " << *a << endl << a+1 << " -> " << *(a+1) << endl;
}

We can see that, for one, the addresses of do increment normally (take my word for it :)) and that *a=a[0] and that *(a+1)=a[1]

Sending and returning pointers/arrays from functionsEdit

Here is an example to look at: (Ignore the "new" thing in the function. I will explain that next.)

#include<iostream>
using namespace std;

int *input(int length);

void output(int *a, int length);

int main()
{
     int l;
     cout<<"Please enter the length of your array: ";
     cin>>l;
     cout<<endl;
     int *a= input(l); 
     output(a, l);
}


//Returns the pointer that is pointing to the beginning of the array
int *input(int length)
{
      int *array= new int[length]; //allocates an array of non-constant length
      for(int i=0; i<length; i++)
         {
               cout<<"Please enter the values one at a time: ";
               cin>>array[i];
               cout<<endl;
         }
       return array;
}

//Outputs all the elements of an array of values of length length (lol)
void output(int *a, int length)
{
    for( int i=0; i<length; i++)
    {
          cout<< *(a+i) << endl;
     }
}

As you can see in this program, I wrote a simple program that takes in array and outputs it. You can see examples of the syntax used for this. Other than the syntax, there is only one other important thing to note about this program. It is that I always sent in the length of the array. This is an important thing to remember because pointers and, as a result, arrays do not natively hold their own lengths. In my for loop example, if I hadn't had the length then my loop would have just continued to run and eventually give me an error.

Dynamic Memory AllocationEdit

The last basic application of pointers is with dynamic memory. What is dynamic memory? You might be asking. It is a form of memory allocation that does not happen at the beginning of the program. We see that when we have written programs up to this point, we have to give every variable a name and a type and give every array a length. This is done so that the compiler can make sure that there is enough RAM to run the program. Dynamic memory allows us to bypass this. Using the new operator, we can create arrays of any length depending on the situation. This gives us an oportunity to make arrays of a variable length. The utility of this really does depend on the situation and we will become more acquainted as we see its applications