[SOLVED] A question about the C address-of and indirection operators
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Rep:
A question about the C address-of and indirection operators
I've been reading about "null pointers" in this Stack Overflow post, but I have a few questions about the part I've quoted below from it. While I DO understand what the address-of and indirection operators are and do and why I would use them (including what "dereferencing" means); The explanation quoted below, and the code, it just doesn't make sense to me in what it's actually saying.
Can someone just explain the explanation highlighted in bold below, and what that code below the explanation is actually saying and doing in plain simple english? Because while the address-of operator and indirection operator by themselves is ok, put together I just don't know how to interpret what it's actually saying and doing. I'm sorry, but the explanation below and code below it is very confusing to me to try and understand.
Quote:
In C, the unary * operator is the dereferencing operator. If x is a pointer, then *x is what x points to. The unary & operator is the address-of operator. If x is anything, then &x is the address at which x is stored in memory. The * and & operators are inverses of each other: if x is any data, and y is any pointer, then these equations are always true:
Can someone just explain the explanation highlighted in bold below, and what that code below the explanation is actually saying and doing in plain simple english?
Those statements are the correct definitions of each of these.
Sorry to say, but they seem to be written in simple English:
Quote:
If x is a pointer, then *x is what x points to.
Quote:
If x is anything, then &x is the address at which x is stored in memory.
Minus the added explanations they gave, do you understand these two statements?
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
The first one sort-of, the second one is very confusing, so definitely no for the last statement.
Like I said above, I get what the address-of and indirection operators are. But that explanation above, let alone the code below the same explanation is too confusing.
Note: This is for C++ where the reference can also be a variable, in C, & just gives the address of something.
Reference = The location of your home in your mind.
Pointer = The location of your home, written in pencil, on a sheet of paper.
The reference in your mind doesn't change, you'll always know where your house is, if you want to know where your house is, you look at your mind and you'll know.
The pointer can change. You're inviting me to your house, so you send me the pointer to your house (the address) on the paper.
I take the paper, look at the address, and come visit you, we have a nice chat and you tell me of a great restaurant, erase the address of your house from the same paper and write the one of the restaurant on it.
This is kind of a limping analogy with many flaws, but basically, the reference to your house in your mind is always valid, (not in reallife, where you can lose your memory etc), you can't do pointer arithmetic on it, it's always pointing to your house, and the reference is created when you gain knowledge of it. (in code terms, a reference is 'never' an empty variable, it must always be instantiated, either directly with assignment, or, in C++ through an initializer list)
A pointer is just a variable that acts like a wormhole to something.
To use the wormhole as the type it's declared as, you put the asterisk in front of it.
Code:
your_house_pointer++ = the pointer to your house is now points at your door neighbor
*your_house_pointer++ = your house is now the next door neighbor
References don't need that, they're a direct link to the destination and always change the object.
Code:
your_house_reference++ = your house is now the next door neighbor
*your_house_reference++ = no level of redirection, error
In C, you only have pointers, and the ampersand is just to grab an address, so all you can ever do is
Code:
pointer * p = &variable;
So in C you always have to keep dereferencing in mind.
When dealing with structs:
These are the same, with each asterisk in front of a pointer, you reduce the pointer level by one.
Remember strings?
Code:
char blah[]
That [] is also a dereference, and you can technically use it on everything, even if the targed is not an array, if you keep the index at 0,because 0 is the pointer + 0, aka the same address.
Otherwise it's
Code:
pointer + (index *sizeof(type))
That's why string[0] is the first character, string[1] is the second character, and in the cse of a simple variable:
Code:
your_house_pointer[0]
*your_house_pointer
are both equivalent.
Written like that, any operation on them operate on the house directly.
And since the asterisk acts as a dereference, you can then use ampersand on it to get the address of the object it points to.
Code:
#include <stdio.h>
int main(int argc, char *argv[])
{
int house = 10;
int restaurant = 20;
int * paper = &house;
printf("The paper points to %d, your house \n", *paper );
paper = & restaurant;
printf("The paper points to %d, the restaurant \n", *paper );
int * second_paper = &(*paper);
printf("The second paper points to %d, the restaurant \n", *second_paper );
second_paper = &paper[0];
printf("The second paper, thanks to that weird array trick, points to %d, the restaurant yet again \n", *second_paper );
int ** third_paper = &paper;
printf("The third paper, is now a pointer to the pointer 'paper' which, in turn points to %d, the restaurant yet again. \n", **third_paper ); // note the double asterisk, one for each level of pointer
*third_paper = &house;
printf("Since third paper is a pointer to the pointer 'paper', and we have gone one level of reference toward the destination, this is like changing the address on the 'paper' itself. \n");
printf("The original paper now points to %d, your house again \n", *paper );
return 0;
}
*
The most fundamental things you should retain are the first two statements.
I completely agree, just wanted to add a comment: actually java was developed because [it looks like] pointers are confusing a lot of people.
A pointer, which is actually an "address of anything", means the memory location where that given anything is put/stored. Basically we always work with pointers, just we give names to them. For example:
Code:
int x;
will occupy memory for an integer and x will mean "the integer at the location associated with that variable (named x)". You will not see directly the address of that location, but if you are interested you can use &x to get it. When we write x (any variable) we always mean a memory location, and we use the type of that variable to know what is stored at that location.
Furthermore you can handle these pointers in variables.
Code:
int *y;
y = &x;
will occupy a memory for a pointer and we store the location of integer x in this memory. Now we can say it is y instead of "a memory location where we store the location of an integer which is named x".
& means "address of...". * means "data stored at...". So the whole string means "data stored at address of x" And the data stored at the address of x is x! The double equals sign indicates a test for equality.
#include <stdio.h>
void main(void)
{
int x = 5;
int *y = &x;
printf("Address of x: %p\nValue at address of x: %d\n", &x, *(&x));
printf("y=%p\nValue at y: %d\n%p\n", y, *y, &(*y));
}
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881
Original Poster
Rep:
Quote:
Originally Posted by hazel
Code:
*(&x) == x
& means "address of...". * means "data stored at...". So the whole string means "data stored at address of x" And the data stored at the address of x is x! The double equals sign indicates a test for equality.
Yes, I know the & means address-of, and I also already knew that the double equal signs means "equal to". It was the meaning of putting both the address operator and the indirection operators together that is confusing, hence my question.
Quote:
Originally Posted by rtmistler
Suggest you please show a compiled example using:
Code:
&(*y) == y
Here is a compiled answer for the first one:
Code:
*(&x) == x
...
I already did type up an example last night before I posted this thread, but I was still confused as what putting the address operator and indirection operators together actually means - let alone trying to follow the explanation quoted in my OP. And in all honesty, I'm still confused as what both "&(*y)" and "*(&y)" actually means and what the difference is between the two - let alone what's actually happening if I do that. Let alone why on earth I would actually do that.
Again, it's ***not*** the operators by themselves that is confusing, it's putting them together like that that's confusing.
Nevertheless, this is what I done before posting this thread last night (my time that is),
Code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int x = atoi(argv[1]);
int *y = &x;
if ( &(*y) == y ) {
printf("x = %i\n", x);
}
else {
puts("else statement executed");
}
return 0;
}
//read y --> x address-of y
(as you can see, I tried to type out what I thought it meant, but it was still confusing)
/* changed 'int' to 'long' to have a uniform size */
#include <stdio.h>
#include <stdlib.h>
int main (void) {
long x = 0x20200103;
long *y = &x;
printf ("x=%lx\n"
"&x=%lx\n"
"*(&x)=%lx\n"
"y=%lx\n"
"&y=%lx\n"
"*(&y)=%lx\n"
"&(*y)=%lx\n"
, (long)x, (long)&x, (long)*(&x)
, (long)y, (long)&y, (long)*(&y), (long)&(*y)
);
return 0;
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.