To proceed to the next sections in our discussion on C programming language, we should learn the concept of void pointers i.e. pointers of no specific type, and type casting, i.e. manually changing the data type of a variable. Type conversion can happen automatically (implicitly) or manually (explicitly). The later is termed as type-casting. Let us see that with an example.
In this example, we have two integers and we find their quotient. Since the first number is odd, the result will be a fraction, so we have to store it in a float type variable. In the first part, in line 5 the right hand side of the equation is an expression having an arithmetic operation on two int type variables. So their result will be of int type. This is how computer arithmetic works. So the result is the integer part of the actual result. In this case it is 8 instead of 8.5. But since the left hand side of the equation is a float, this result is converted into a float type before storing it into the variable quotient. So in the output we get the result in a floating number format as 8.000000. This is automatic or implicit conversion.
Now lets look at the second part of the program. In line 8, in the right hand side of the equation, we first explicitly convert number1 into a float type variable, then divide it by number2. So the result will be of float type. So the computer can correctly evaluate the answer to be 8.5 in this case. This is reflected in the output.
Similarly we can explicitly change the type of pointers. The type of pointers is significant because it denotes the type of the variable it points, i.e. the size in bytes of the variable. Increment operation on pointers depend on this byte size. For example when we increment a char pointer, it points to the immediate next byte in memory. But when we increment an int pointer, it points to the 4th byte from its previous address in memory. We can illustrate this with an example which was also a question in one of previous GATE exams.
This is a fairly complex program. You’ll need to understand pointers and memory in a fundamental manner, but I’ll try to explain the best I can. Things get stored in the memory (RAM) is a way analogous to how water is filled in a bottle. That is, it is filled bottom up. Let us say that first 1000 addresses of the memory is already full. If an int type variable (4 bytes) is inserted next, it will successively occupy 1001, 1002, 1003 and then 1004th byte in RAM. In the int variable, the rightmost byte or the least significant byte (LSB) will be stored in location 1001 while the leftmost byte (MSB) will be stored at location 1004.
In this example, 300 is stored in 4 bytes of memory as 00000000 00000000 00000001 00101100, where the byte stored in address 1001 is the LSB i.e. 00101100. The pointer to this variable will point to address 1001 and the type of the pointer will denote that the variable occupies 4 bytes.
So in line 8, we change the type of the pointer (rather create a new pointer and assign the address of the variable) to this variable to be of char type. A char type pointer denotes the the variable it points to will occupy a single byte, so when we increment the pointer, it will go to the immediate next address.
In line 11, we increment this char type pointer with the pre-increment operator. This results in incrementing the address before the right hand side of the equation is executed. Thus first the pointer charp points to 1002, and then stores a value of 2 into it. The previous byte stored in 1002 was 00000001 as we see above, but now it got changed to 00000010. Thus the 4 bytes in memory of the integer variable a becomes 00000000 00000000 00000010 00101100 which corresponds to 556 in decimal. This is what we print in line 12 and check the output.
This example should illustrated how important the type of a pointer actually is. In dynamic memory allocation, while allocating a chunk of memory, a pointer to that chunk of memory is returned. But the Operating System does not know what type of data will be stored there, so it cannot determine the type of this returned pointer. So a generic pointer is returned which can be type-casted to the required data type. This is called a void pointer. We’ll discuss more about void pointers and dynamic memory allocation in the next blog.
If you liked this article please comment and show your support and interest so that I’ll be motivated to continue this effort. Like our facebook page if you haven’t already. And if you have any questions please comment. I’ll try to reply all.