 This part of the session, I would like to describe how I believe pointers could be introduced to our students. By now, the students would have understood that there are memory locations which are tagged by the names that we give them and that these locations form a sequence of consecutive places where values can be kept. We would now like to emphasize to them that while we normally deal with the values stored inside these locations, the location addresses also can be deployed meaningfully. Use of these addresses of the location and the values therein has been handled traditionally in C C plus plus at an extremely low level and that is the reason why pointers are predominantly used in C, used less in C plus plus and not used at all in languages such as Java. Many puritanical programmers consider the use of pointers as a very dangerous thing. However, pointers and pointer arithmetic forms the very crux of many good programs that have been written. Your power to write programs, of course sometimes the programs become unreadable. In general, in C C plus plus, you cannot avoid using pointers. There are certain simple things also which cannot be done without pointers and therefore understanding pointers is a necessary event. In particular, when I want to pass parameters in functions by reference, I need to use pointers. So, we will see one example of this and input output functions in C C plus plus such as scanf will necessarily require a pointer. The way I like to introduce pointers to students is to tell people that memory consists of many locations. Each location has a unique address. Usually, the address inside the machine starts with 0. The smallest units of addressable memory is a byte. That means you can address individual bytes. For numerical values, we use larger locations which are made out of composite bytes. So, you put two bytes together, four bytes together, eight bytes together and you get a larger location. Now, if you consider int float and care variable types in arrays and have a declaration int float a3 care c4, assume that you have assigned these values, 573 to m, some 673.85 2 to a0, some very small value to a1, some very large value to a2 and you have assigned individual characters u, n, i, x to c0, c1, c2, c3. Please note, I am not talking about a string here. So, do not search for a backslash 0. These are just arbitrary assignments made here to demonstrate the notion of a pointer. Now, if these variables are listed and if we assume that these have been allocated consecutive location in the memory, what internally will happen is something like this. Suppose the first location is allocated at the address 10000, then the addresses of all locations will follow like this. The location 10000 will contain the value of m since an integer is ordinarily allocated 4 bytes, the next available location address will be 100004 which will be given to a0. Now, a0 is a floating point element, it also requires 4 bytes, next element is 100008, subsequent is 1000012, etc. At this 1000012, I have the element a2 which contains this large value and it is 4 bytes long. The next element is addressed at 1000016. This then will become the address of the element c0 which contains u. However, this is a care array, so it requires only 1 byte and therefore the address of the next location is 100007. These then are the addresses and these are the names. Now, this is what happens internally and we should particularly tell our students that ordinarily we have nothing to do with these addresses. We deal only with the name and the corresponding value. However, it is possible to deal with these addresses which are actually pointers to memory location because they point to specific memory location. Now, 10000 is thus an address pointing to m which is a int type, 1000012 is an address pointing to a2 which is a float type, 1000016 is an address pointing to c0, 1000017 is an address pointing to c1. What is important to emphasize to our students right at the beginning that while the addresses simply look numerical and therefore exactly similar in nature to us they are not. Internally c plus plus makes a great distinction between a pointer which points to an integer value and a pointer which points to a floating point value and a pointer which points to a character type value. Ordinarily we do not deal with these pointers at all. We use names and values, but c plus plus permits us use of pointers within a program. A location address can be found and stored as a pointer and contents of such address can be accessed and used. Notice that as I said we normally deal with these names. The first question is if a pointer is defined as an address to a location given the name of the location how do I find an address and where do I store that address. The corresponding reverse problem is given the address stored in some appropriate variable which we do not know how, but given an address how to find the corresponding value. The corresponding value which is located inside this name m. These are the issues with which the pointers deal with. So for example consider the location name m its address in our example is 10000 value of m is 573. The value at address 10000 is 573. So even if there was no name m if you knew the address you can relate it to the content 573. Of course we deal with that. As I said we require two possible operations given a name what is its address. Given an address what is the corresponding value stored in that location. These two are made available to us by the operator n and the operator star. Note that the symbol star is used as multiplication operator in the arithmetic expression symbol and is used in our logical expression. But in a standalone fashion associated with something that we shall shortly see these stand for operators dealing with addresses and their content and is called the address operator. When it precedes any name it returns the address of that name. Star is called dereferencing operator whenever it precedes a name it actually gives us the value contained in the address referent by name. For example and m will give us the address of m. Star p will give us contents of the location whose address is stored in p. What is p? Is p an arbitrary integer variable because we think that addresses are simply numbers and they can be stored in integer variable. The answer is a plain no and this must be told to our students emphatically that while the addresses are numerical values c c plus plus does not permit us to deal with these addresses as plain numerical value. If at all we want to extract an address and use it even numerically for doing some operations as we shall see it must be stored in specially defined variables called pointer variables. How do I get an address if I have a variable p which is a pointer variable I simply say p equal to and m. Notice that the and operator will get us the address and this address will get stored in p. How do we declare p and how does it hold an address? Here are some examples. There is a special type called pointer type and I can say int star p. Why do not I say pointer p? Simply the reason is as I said c plus plus distinguishes pointers of different types. That means pointers which point to names of different types. So a pointer which pointing to a integer variable a pointer which is pointing to a floating point variable a pointer which is pointing to a cal type variable are all considered separate types of pointer. And the simplest way to define a pointer since every pointer is always associated with a type c plus plus has decided as design a mechanism by which you write the type and then you write a simple star followed by the pointer variable name. It means that you are defining a pointer which points to variable of that type. So here is an example int star p defines name p to have a type int star which means it is a pointer of the value type int. Please note that p itself is an address. So it is actually a numerical value. But can I say p equal to let us say one lakh twelve thousand? The answer is no. This is a wrong thing because while p is contains a numerical value it is not an arbitrary numerical value that we can assign. It has to be a valid address of one of the variables or array elements in your program. And that valid address must be calculated by c c plus plus only. You and I cannot do that because we simply do not know what any address of a location is. And this can be found by saying p is equal to and m. So only such an assignment can permit us to get a value for p. Of course once we get a valid address there are numerical operations which are possible on p which we shall see shortly. Here is a code m n int star p. m is equal to 25. This is a normal assignment. m is an integer variable. p is equal to and m. This means the address of m is assigned to p. n is equal to star p plus 3. This is a valid statement. Why? 3 is a value. p is a pointer but star p is a value. Remember star is a dereferencing operator. So star p actually means the value contained in the location pointed to by p. This is nothing but m whose address we got it here. Since the value of m is 25, star p is replaced by 25. 25 plus 3 is 28. So you get this value. We can declare pointers for any data type. So I have int star p 1, float star p 2, cache star p 3. This will allocate separate memory locations for these three pointers. As I said each can contain an address which ordinarily itself is a 32 bit number. So the address can be a very large value between 0 to 2 to the power 31 minus 1. When I write p 1 is equal to and m where m has a value 573, p 1 will be assigned what value? p 1 will be assigned the value which is address of m. What is the value of star p 1? The value of star p 1 is the value contained in m which is 573. So here is an example. If I print the value of m using c out star p 1, I will get actually 573. We can also print the value of pointer itself which is meaningless to us ordinarily. Suppose I say c out p 1, I will actually get the address contained in p 1 and in fact whenever you ask c out to print the value of a pointer variable, it will print it in extra decimal because it knows that it is not a meaningful value to your program. It is an address which is in turn. We can actually increment the value of a pointer. For example, if we say p 2 is equal to and a 0, notice that this is an address operator a is an array. So the address of the 0th element of array is stored in p 2. Now when I say p 2 plus plus, p 2 will not increase by 1, but it will increase by as many bytes as are associated with that type of array a. Since that type requires 4 bytes, the address will be advanced by 4 bytes. Why? Because when we say p 2 plus plus, the implicit understanding of c plus plus compiler is that you now want the pointer to point to the next element of this array and the next element of this array is 4 bytes away, not 1 byte away. Now this is automatically handled by the compiler. You and I do not have to do any. Now if I say c out less less star p 2, it will print the value of a 1 because p 2 has been advanced by 4 bytes because of this instruction. Here is an example program. I declare m n a 3 is a 3 element array. I assign p 5 73 to m and some minus something, something value to n. I define two pointers, integer type pointers because all of these are integers, p t r 1, p t r 2. I have assigned the values of m and n, I just print them out just for confirmation. I will get m as p 5 73, n as 1, 2, 3, 4, 5, 3. I do what I just demonstrated. I extract the address of m, store it in p t r 1. Now p t r 2 is also a pointer. To p t r 2, I assign a value p t r 1 plus 1. Please note that these pointers are in type. Since integer requires 4 bytes, p t r 2 will have a value which is 4 greater than p t r 1. Since I have declared m followed by n followed by a 3, I would now expect that p t r 2 points to n if p t r 1 was pointing to m. I try first to print the value of the pointers p t r 1 and p t r 2 and then I try to print the corresponding values which are pointed to by these pointers by saying star p t r 1 and star p t r 2. If I execute this program, this is what would happen. Value of m and n is this and this. The pointers have these two values. These are the values which are written by what you call in hexadecimal by c plus 1. The corresponding data values are 573 and minus something, something, something, something. Why is that? Why are we not getting the right value of n? That is because n need not be located 4 bytes away from m. There is no guarantee that the compiler would do that. The only guarantee compiler gives is when I have in as a pointers pointing to array elements because array elements are only always allocated consecutive locations. The correct way to deal with two different values m and n is extract the address of m separately by an AND operator, extract the address of n separately by an AND operator. Now if I print these, I will get the right values of values pointed to by those pointers namely the value of m and n. These kind of explanations I have found very useful to the students who otherwise get lots of confusion in the case of pointers. What is important to tell them is that if you are dealing with arrays, then pointers which have successive values of that particular type will always point to successive elements of an array and that is because array elements are always allocated successive locations. So if I output a 0, a 1, a 2 and I assign address of a 0 to pointer 1, I add 1 to it to get pointer 2, I add 2 to it to get pointer 3 and then I print the pointer values and then I print the data values which are pointed to by them by saying star ptr 1, star ptr 2 and star ptr 3. Observe what I will get as output. The actual values are these, the pointers have these values and the corresponding data values are the same as these. Notice that the pointers which are printed by my program, those of you who can easily read hexadecimal, this value ends in 5 c and this value is 6 0, it is exactly 4 bytes away from here. This value ends in 6 4, it is exactly 4 bytes away from here. It confirms that c c plus plus will always allocate consecutive locations to elements of an array. Of course the consecutive locations will not be 1 byte away, they will be as many bytes away as are required to represent one value of that type. So this is floating point type or integer type, these will be 4 bytes away. As I said this is merely an introduction to the pointers, there is much more to the pointers, the more important things are to talk about passing parameters to function. Ordinarily when we deal with functions, initially we tell them about passing parameters by value. So for example when we pass, when we write a function f with a parameter int x and a parameter int y and we call it in our program by saying c is equal to f of a b. We presume that a goes to x, b goes to y, the function is calculated and I get the sum returned back here which is assigned to c. Does the value of a and b change? Well it does not because this method of parameter passing actually copies a value. Let me skip this example, this is a very simple example. The point is when we invoke the functions f, the values of x and y are copied and sent to the function. So even if the functions f these or changes the value, the changes not reflected in the original value. Since those values are not copied back, only one copy is sent. Now if we want to tell the function that if you change the parameter which I have sent, do not change your local copy, but change me then by mentioning me as a parameter is not adequate. What I have to do is when I call the function, I tell the function that look I am not giving you a value, but I am giving you a pointer. So whatever you do with that variable I will get changed because that pointer is pointing to my address. This is what is known as pointing, calling by reference. If I pass the parameter as a star, as an and, as an address then I will get an updated thing. The array names are always passed as addresses or pointers. That means whenever I pass an array name as a parameter, it automatically treats that array name as the pointer to 0th element of the array. That is the reason why when an array is passed as a parameter to any function and in that function if modify the value of any element of that array, that change is reflected in the calling program because what has gone out there is not a copy, but what has gone out there is a pointer to the array and therefore changes happen there. Here is that example. I say int, main, whatever, swap and x and y and this swap function is written as int star a int star b. So whenever I exchange a and b, it reflects back on to x and y and x and y gets changed. The I o function since c plus plus remember I said on the very first day that it is scary to explain and scary for students to understand the use of and in a scan f, but once we define the pointers and tell them how pointers work, we will see that it is very easy to explain the function scan f particular. The parameters, this is an explanation for scan f and print f. I am not going to those details, but what is important to say is the print f function, but let us look at the scan f function. The scan f needs to be passed pointers to the argument. Why? Because when we call scan f function, it actually collects a value from the input and inserts it into the variable. Now, if that variable was merely a copy, that value remain inserted in there. We want that value back. So therefore the parameter that we give is an address parameter. So for example and where variable 1 and variable 2 etcetera is the way to call scan f. So here is an example in this scan f when I say and x and y, then whatever value is read by scan f is given to me as value of x and value of y. Therefore, when I say c out, I will get actually the input value. Why am I not using an and operator here? Simply because it is not necessary. Name is an array and by convention c plus plus always passes as a parameter the address of the name of the array name. Therefore, if I read something here, it will automatically reflect in this variable. This is the essence of pointer. There are a lot more things that you can do with pointers. Sadly, there are many programmers who write very difficult to understand code by using only pointers. So for example, it is fashionable or it was fashionable at one time among c programmers to not to use arrays with their indexes. So instead of writing c i, they would write star c plus r because star c is a pointer, i is an index. Now this might make sense to a tricky and in their ways, elegant programming. I personally consider that as poor programming because a program which cannot be understood by another human reader easily is a poorly written program in the modern context, where programs are increasingly written by someone and used and modified by someone else. I do not have the privilege of writing programs for my own sake. I always write programs which will be shared. So good coding practice should mean that you should not try to use such tricks. But what is important is to understand that pointers are extremely critical and important. A few things such as parameter passing by reference cannot be done without pointers and of course they can be used for some elegant coding practices. Here is another example of scanf where an input data line contains this. So notice that there is no blank space here. Observe that all the while we are shouting at c in that without a separation of a blank, I cannot read anything. But the scanf can read the entire character string and the scanf has the ability to extract portions of that string based on the format that I have described. I suggest that we take the tea break now