 Hello, and welcome back. In this lecture, we are going to have a brief introduction to pointers in C++. Here is a quick recap of some of the relevant topics we have already studied. We have looked at basic programming constructs, we have looked at the usage of variables in programs and we have also seen some basic data types like int float, double car, bool and void. Well, we have used void only as the return type of some functions. Nevertheless, that is a basic data type in C++ that we have seen. We have seen the usage of arrays and matrices and we have also looked at programs to solve some interesting problems. In all of this, we have basically used variables as named memory locations. So, whenever we needed to access memory locations, we access them through the names of the corresponding variables. In this lecture, we want to break away from this paradigm of accessing memory locations only through their names. We want to try to see if we can access memory locations through their addresses. So, we must first understand what are addresses of memory locations. And in this lecture, we are also going to see the address of operator in C++, which naturally leads to a new data type called the pointed data type in C++. Now, let us look at memory and addresses. Main memory is really a sequence of physical storage locations. So, I have denoted here the different locations by different colors. This is one location, this is the next location, this is the third location and so on. Now, each location can store 1 byte or 8 bits of information. We will call that the content or value of that location. So, for example, this location stores the content 1011, 1111. And each physical memory location also has a unique address by which it can be identified. This is like an index of that memory location in the entire sequence of memory location. So, typically, when we deal with addresses and when we print them out in C++, addresses are printed out in the hexadecimal notation. So, therefore, in this lecture, we are going to look at addresses in the hexadecimal notation. So, for example, this is an address in hexadecimal notation. This is the address of this memory location and at this memory location, the content or value is 1111, 0000. So, 40a is the address in hexadecimal of this memory location and 1111, 000 is the content or value of this memory location. Now, if you recall, in an earlier lecture, we said that when a program is executing, this is also called a process and executing program is called a process, then the operating system allocates a part of main memory for use by the process. So, this is the main memory, the operating system allocate this part for use by the process. You would also recall that this memory allocated for a given process is actually divided into three segments. We have the code segment which stores the executable instructions in the program, the data segment which stores dynamically allocated data and we will see this in a later lecture and then there is the stack segment which stores the call stack. If you also recall, every local variable of every function in a program is basically allocated in the activation record of that function and the activation record is stored in the call stack in the stack segment. So, basically every local variable of every function in your program actually resides in the stack segment. Now, let us see how this might look like for a simple program. Here is a simple C++ program and I am just focusing on the declarations over here. These three named variables are like the named drawers of Dumbo or you can think of them as named locations in the stack segment. One might ask, what are the addresses of the memory locations corresponding to these three variables in the stack segment? Well, this is how the picture of main memory for this program might look like. This is the stack segment where all the local variables of every function are going to be allocated. So, when I have this integer variable A, since we know that integer variables require 32 bits or 4 bytes, I need to have 4 bytes for A in the stack segment. However, each addressable memory location can only store one byte. So, I must have 4 memory locations reserved for the variable A and these 4 memory locations for a variable will be contiguous or successive memory locations in the stack segment. Similarly, for the variable B which is of type float, if you recall we need 32 bits for float data type. So, I need 4 bytes and once again 4 consecutive memory locations in the stack segment will be reserved for storing the values of the variable B. Character however requires just one byte and so we are going to reserve just one byte or one location in the stack segment for character C. So, this is how the different variables are going to be stored in different parts of the stack segment. Now, if we also bring into account the addresses of these locations in the stack segment, this is how the picture might look like. Once again, these addresses are given in hexadecimal notation. So, that is why I have prefixed them with 0x. So, this might be the address of the location in the stack segment where the value of this character variable C is going to be stored. These are the addresses, note that there are 4 consecutive addresses here of the 4 consecutive locations in the stack segment where the value of the variable B is going to be stored and similarly these are the 4 consecutive addresses of the 4 consecutive locations in the stack segment but the value of the variable A is going to be stored. And now if you look at some real C++ code that uses these variables, what you will notice is that in this code I am basically accessing these memory locations by their names. I said read in some value and store it in the memory locations corresponding to this variable A. Read in some value, store it in the memory locations corresponding to this variable C. Read the values from the memory locations corresponding to the variables A and C, compute their average and store it in the memory location corresponding to the variable B. So, all the accesses are by names of the corresponding variables. So, one might ask that can we access memory locations not by the names of the corresponding variables but by their addresses since they also have unique addresses and what we want to see is how can we do this in C++ and this will be the primary motivation for us to study pointers in C++. Well, it turns out that yes we can indeed access memory locations by their addresses and we will see how to do that in this lecture in the next. But in order to do that we must first be able to find the addresses of memory locations corresponding to different variables. I must be able to first find the address of the locations corresponding to variable A before I can use that address to access the locations corresponding to variable A. Now in C++ we have a special operator which I will call the address of operator. It is represented in programs by this ampersand symbol and it is a unary operator and we can use this operator to basically get the address of a variable. So, if A is a program variable ampersand A will give us the address of the variable A in memory. Note that this is a unary operator, it takes a single argument and in particular if you take the variable A and apply this unary operator you actually get a C++ expression and therefore we must worry about how to evaluate such expressions. So, we must worry about operator precedence, associativity and all of that whatever we have studied in earlier lecture. But for our purposes we will just simplify life and use parentheses to very explicitly indicate what is the precedence of the ampersand operator and what we wanted to associate it. So, if I want to get the address of the variable A I will write ampersand A and put parentheses around ampersand A to explicitly say that I am interested in the address of the variable A. So, if A is an integer variable and if ampersand A is an expression one might ask well what is the type of ampersand A? Every expression must have a data type and here is where we encounter the new data type that we are learning today which is pointer to an already existing data type. So, in this case it is a pointer to int and this data type in C++ will be written as int star, int space star. So, if B is a float variable the type of ampersand B will also be pointer to float and will written as float space star and in general if x is a variable in your program of type P then T star denotes the type pointer to T and when you write ampersand x this is an expression whose type is a pointer to T and this will give you the address of x. Well, now one might ask that if int star is a legitimate type can't I have a variable of that type and indeed you can have and so here is our original program and now I have added one more variable called pointer A and its type is int star. So, it is basically a pointer to an integer variable. Now, let us for the time being assume that all memory addresses on our computer are 32 bits. So, all memory addresses can be represented by 4 bytes. So, then how many bytes would I need to store the value of pointer A? Remember pointer A is a pointer to an int. So, it will basically contain the address of an integer variable and if an address requires 32 bits or 4 bytes I will need 4 bytes to store the value of pointer A which will be the address of an integer variable. So, let us say that these 4 locations in main memory with these 4 consecutive addresses are reserved for this variable pointer A and now when I execute this code pointer A assigned ampersand A one might ask what is the value assigned to pointer A? Well, this should be the address of A but well A has been allocated 4 locations. So, there are 4 addresses which of these 4 addresses should be assigned to the variable pointer A. It turns out in C++ the semantics is such that we are going to assign the address of the first among the 4 bytes allocated for A in this variable pointer A. So, the first among the 4 bytes allocated for A had the address 00402 in hex. Therefore, we are going to assign 00402 in hex to the integer pointer variable pointer A. If you look at pointer A its content or value is the address of the first byte allocated for A which is hex 00402. But the address of pointer A is hex 0040A which is the address of the first byte allocated for pointer A. So, let us ask if we can have pointers to pointers themselves. Suppose pointer A is a variable of type int star which means that this is a pointer to an integer variable. Then what is the type of the expression ampersand pointer A? Well, if you recall we said that if a variable x is of type t then ampersand x is of type t star. So, applying that rule type of ampersand pointer A would be int star star. I have used different colors here to explain the meaning of this. So, this blue star is saying that this type is a pointer 2. So, this blue star corresponds to this blue letters here saying pointer 2. So, this is a type which is a pointer to the black part and what is the black part that is a pointer to an integer. So, this is a pointer to a pointer to an integer. Note we did not put parentheses around int star and then put a star, but instead we put two stars right after int and this is important. We should not write a pointer to pointer to an integer like this, we must write it like this in C++. Now, how far can we take this as far as we want? For example, int star star star star is a legitimate pointer type in C++. What does it represent? Well, this black part is saying it is a pointer to something in the purple box. What is in the purple box? That is a pointer to the green part is saying it is a pointer to something in the purple box. What is in the purple box? The orange part is saying that it is a pointer to something in the purple box which in turn is a pointer to something in the purple box and that is an int. Now before we end, here is a brief note about pointer declarations. If you look at a simple C++ program, a declaration like this assigns the data type int to all of x, y and z. However, if you have a declaration like this, it is not that A has the type int star and B also has the type int star and C has the type int star star. Here the way C++ works is that A has the type int star. So, it is a pointer to an int. B however, just has the type int, C has the type int star and not int star star. It is not a pointer to a pointer to an integer. So, you should remember this when you are declaring your pointer variables. And to sum it all up, here is a simple C++ program for printing addresses. We have the same three variables we had earlier. We have introduced three new pointer variables, each a pointer of the appropriate variables data type. And then we just take the addresses of these three variables and put them in the appropriate pointer variables and print them out. So, I encourage all of you to compile and run this program and see how memory addresses look like. And if you are wondering, did we learn all of this just to print memory addresses? The answer is no. Just wait for a few more lectures and you will see that we are going to make a lot of use of pointers in our program. So, in summary, we looked at memory and addresses. We looked at the address of operator in C++, which gives rise to the pointer data type. And we also saw some simple usage of the pointer data type in C++ programs. Thank you.