Address of variables contd.
When working with variables in C, it’s essential to grasp the concept of memory addresses and how they can be stored in variables for various purposes. This tutorial will explore the use of the address-of operator (&) and type casting to manage memory addresses effectively.
When you use &a1, it actually gives the pointer. So now, you can even store this value into a variable.
Storing Memory Addresses:
In C, the ampersand (&) operator allows you to retrieve the memory address of a variable.
For example, if we have a character variable named a1, &a1 will give us the memory address of a1. You can also store this address in another variable for further manipulation.
#include<stdio.h> int main() { char a1 = 'A'; unsigned long int addressOfa1 = &a1; printf("Address of variable a1 = %p\n", &a1); return 0; }
Test this program in Eclipse IDE
Now, if I do this, let’s see whether the compiler is happy with this or not. Build the project, and there is one important warning let’s read.
Compiler Warning:
The warning says that “initialization of ‘long unsigned int’ from ‘char *’ makes integer from pointer without a cast”.
This warning arises because the memory address obtained from &a1 is treated as a pointer, not a simple numeric value.
You should remember that &a1 is not a number. The compiler sees it as a pointer. There is a difference between a number and a pointer in ‘C.’
Data Type Mismatch:
Here, you are trying to assign &a1 entity to a variable addressOfa1.So, addressOfa1 represents a variable. So, here the data type of this one is unsigned long int. We used unsigned long int because unsigned long is 8 bytes. So, the address size is 8 bytes. That’s why I have chosen unsigned long int. That’s about the left-hand side.
Now let’s take a look at the right-hand side. &a1 is pointer data. Pointer data are represented by pointer data type in ‘C.’ So, the type here at the LHS is unsigned long int, and the type at the RHS is char*.
The warning is that you are trying to take an entity of a different data type, and you are trying to assign that to an entirely different data type variable. That’s why there is a data type mismatch. So, &a1 is not just a number; this is a pointer, which belongs to the pointer data type. And the pointer data type happens to be char* in this case. When we cover pointers so you will understand more about that.
Here, we are trying to assign a pointer type data into a variable. Hence there is a data type mismatch warning.
To solve this issue, convert pointer data type into variable data type using type casting.
Solution: Type Casting:
To resolve this issue, we use type casting. Type casting involves converting one data type into another.
In this case, Unsigned long int is called as typecasting.
We are converting &a1 entity into unsigned long int type. This whole thing is now a number. So now there is no pointer. So, we converted the pointer into a number of unsigned long int.
Let’s see how the compiler responds to that. Let’s do the typecasting.
Write the parenthesis and give this data type name unsigned long int. And after that, let’s print the addressOfa1 value just like an integer. For that Integer, we use %d.
But remember that %d for integer, but this is a long integer, so %ld. Remember that you need not use %ld here. Because this is unsigned data, so addresses are always unsigned. That’s why, instead of giving %ld (which is for signed), you can mention %lu long unsigned integer.
Let’s run this code.
You can see that the warning is changed to something else. Now, it says “cast from pointer to integer of different size.” So, this warning is coming because the unsigned long int is actually 4 bytes on my machine. Basically, it is compiler dependent as I said previously, so everything is compiler dependent here.
The size of the data type int is 4 bytes, and the size of the long data type is also 4 bytes for this compiler. So, that’s the reason the compiler is saying that here. So, &a1 is actually a pointer data of 8 bytes, and you are trying to truncate that by using long int.
Here we have to use long long int. The long long size is 8 bytes. And to print long long data, you have to use an I64 format specifier. Just use %I64.
Basically, you can also use lld or llu. lld is for a long long integer, llu is for a long long unsigned integer. For MinGW, you have to use here I64d or I64u. So, since we are trying to print unsigned data, let’s use I64u.
Compile and run this. There are no warnings at all. So, now let’s try to print this, so this happens in integer format. (Figure 6)
Let’s convert that into hex format. So you can give X here instead of u. Now let’s run.
The output shows in a hex format. It is printing only 3 bytes because the rest of the bytes are 0. So, the takeaway from this lecture is you can store the pointer as a number(&a1) in your variable(addressOfa1), but for that, you have to use some casting( unsigned long long int). So, here we are using long long int because the pointer is 8 bytes in this machine. That may not be true if you go to the other machine.
For example, if we use ARM-based 32-bit microcontrollers, then the address size will be 4 bytes. It all depends on the architecture. The pointer size is actually architecture-driven. For 32-bit architecture, the pointer size will be 4 bytes; for 16-bit architecture, it will be 2 bytes, like that.
In the following article, let’s study functions in ‘C.’
Get Full Course on Microcontroller Embedded C Programming Here.
FastBit Embedded Brain Academy Courses
Click here: https://fastbitlab.com/course1