YTread Logo
YTread Logo

Pointer types, pointer arithmetic, void pointers

May 03, 2020
So far in our previous lessons we have seen how to work with

pointer

variables. So we understand the basics pretty well, in this lesson we will write more code using

pointer

s and look at some of these concepts. In more detail using some examples, the first thing I want to point out is that pointer variables are strongly typed. What it means is that you need a pointer variable of a particular type to store the address of the particular type of the variable. Therefore, int* or a pointer to an integer will be needed to store the address of an integer, a character pointer will be needed to store the address of a character, and similarly, if we have a defined structure or class by the user, then we will need a pointer to that particular address. just write, but why do we need these strong guys?
pointer types pointer arithmetic void pointers
Isn't it that pointer variables simply store the address of the variable? So why couldn't we have a single type which is some generic type to store the address of all

types

of variables and the answer is that we don't use pointer variables only to store memory addresses but we also use them to dereference these ? addresses so that we can access and modify the values ​​at these addresses. Now as you know data

types

have different sizes like in a typical modern compiler an integer is stored in four bytes, a character variable is stored in one byte, a float variable is stored in four bytes and these Variables differ not only in their sizes but also in how we store information in the bytes that are available for these variables or data types.
pointer types pointer arithmetic void pointers

More Interesting Facts About,

pointer types pointer arithmetic void pointers...

Let's say we have an integer A and its value is 1025 and this is how it is stored in memory. Every parenthesis here is a mouthful. Let's say this particular byte, which is the least significant byte, is byte 0 and then we continue as byte one, byte two and byte three. We now also know that every byte in memory is addressable. Let's say the address of byte zero is 200 now these four bytes must be contiguous. Let's say the address of byte 1 is 201 and then we continue as 202 and 203. When an integer is represented in memory, the leftmost bit stores the information whether this integer is positive. or negative, it is also called sign bit and the remaining 31 bits are used to store the value.
pointer types pointer arithmetic void pointers
So if you see, we have a bit one on the far right with place value 2 to the power of zero and in this particular bit with place value 2 to the power of 10. So the total value that we have in binary here is 1025 in decimal. Now what happens if I declare a pointer to the integer P and store the address of A in P using the business operator? What will happen if I print the value of P, the value of P or the address stored in P will be 200, the address of byte 0? So, we are saying that we have the address of an integer variable starting at address 200.
pointer types pointer arithmetic void pointers
If we dereference this address and try to print *P, we want to know the value at this particular address. Then the machine sees that ok P is a pointer to an integer, so we need to look at four bytes starting with address 200 and then the machine knows how to extract the value of an integer data type. Then it retrieves the value 1025 from these four bytes. Now, if P were a character pointer, upon dereferencing the machine would have looked at only one byte because a character variable is only one byte. If P were a pointer to float, then although float is also stored in four bytes, but the way the information for float is written to these four bytes is different from the way the information is written for a data type. integer, so the printed value would have been something else.
Let's write some of this into a real program and see what happens. In my C program, I will first declare an integer 'a' equal to 1025 and now I will declare a pointer to the integer 'p' and then store the address of 'a' in 'p' using the business operator. Now I will write a print statement like this integer size and we have a sizeof function in C which gives us the size of a particular data type in bytes and now I will write a print statement like this, the address is equal to 'p' and the value is equal to '*p'.
We remove the reference to 'p' to print the value. Now let's see what the result of this program is. No points for guessing, this is pretty straight forward, the size of the integer is 4 bytes, the address. What we are displaying here is an address and the value is 1025. Ok, now I will do a trick here. I will declare a character pointer, let's say the variable name is 'p0'. Now I will try to put the same address that we have in 'p' into 'p0' by writing a statement like this, but this will give us a compile error because 'p0' is a pointer to a character and 'p' is a pointer. to integer.
So what we're going to do here is we're going to type 'p' into the character pointer and then assign the value and now I'm going to write two more print statements. First is "the size of the character is this many bytes" and we use a sizeof method again and second is the address is 'p0' and the value at the address is '*p0', so we dereference, we try to dereference ' p0' now and Let's see what the result is now. The first result line is the size of the integer and the address is 4 bytes, because we are running the program from scratch, this address will not be the previous address, but the address of the previous execution.
This will be a different address by dereferencing the integer pointer we get the value 1025. Now the next line of output is the size of the character is one byte the address is 5373032 which is the same address we have in the second line , but the value this time is 1. Now why is this value 1? Again, if we write 1025 in binary using 32 bits, this will be the representation when we do this typecasting here trying to store the address of 'p' in 'p0' and then address of this particular byte, the rightmost byte is stored in 'p0'. But when we dereference 'p0' because 'p0' is a pointer to a character, the machines say: "Hey, this is a pointer to a character and the character is only one byte, so I'll look at just one byte to see the value and if you see this particular byte in binary is 1 and that's why this output here is one.
Ok, I'll write two more print statements, now one to print the address p plus one and the value at address P plus one. Now, as we know, we can add or subtract an integer constant from a pointer variable. In fact, this is allowed, the only pointer

arithmetic

allowed is adding or subtracting some constant integer value to the pointer p+1 will take us to the address. of the next integer, so it will jump four bytes and take us four bytes ahead. Let's say we also want to print p0 plus one and the value in p0 plus one.
Okay, now let's look at the output of this particular program. a' this time is 4456036, which is what is assigned to 'a' in this particular run. The value is 1025 p plus one is 445 6040, if you see this is 4 bytes more than the address of 'a' because the size of the integer is 4 bytes and 'p' is a pointer to an integer. So incrementing 'p' takes us four bytes forward and this value is a garbage value because we haven't completed anything at this particular address, so there is some garbage in memory that we are collecting. Now the address in 'p0' is also 4456036 which is the address of the first byte, the least significant byte of 'a', the value is 1.
Now p0 plus one is 4456037 here we have a value which is one more byte and this is This is because the character is stored in a byte. Now the value here is four, if you see p0 plus one it will take us to this particular byte, the address of this particular byte and this particular byte in binary is 4. This was to show you how things happen in memory when We dereference a pointer variable by using the Astrick operator and also what happens when we perform pointer

arithmetic

with a particular pointer type. This typecasting of pointer variables from one to another also has some use cases.
We will discuss them later. Now we will discuss a pointer type which is a generic pointer type. It does not correspond to a particular data type and this type of pointer is called

void

pointer and we declare this particular type of pointer using the keyword

void

and using an astrick sign in front of the variable name. Again now we can write something like 'p0' equals 'p', we don't need explicit typecasting like this. The statement 'p0' equals 'p' is valid and this will not give you a compile error because this particular pointer type is not assigned to a certain data type we cannot dereference this particular pointer variable .
So if you try to print star 'p0' or astrick 'p0' you will get an error. We are getting a compilation error. we can only print the address and as we can see here the address is the same as the address of 'a' and if we do arithmetic, if we try to do something like p0 plus one, we access something like p0 plus one, this is also not possible . It will also give you a compile error. We will return to the use cases for void

pointers

in the next few lessons. For now, let's know that there is something called empty

pointers

.
So this was a deep dive into pointer types, typecasting, and pointer arithmetic. We will have a lot of fun with the pointers. in the next lessons. So thanks for watching.

If you have any copyright issue, please Contact