LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-02-2020, 07:58 AM   #1
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
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:

Code:
*(&x) == x
&(*y) == y
 
Old 01-02-2020, 08:30 AM   #2
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by jsbjsb001 View Post
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?
 
Old 01-02-2020, 09:09 AM   #3
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Original Poster
Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
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.
 
Old 01-02-2020, 09:34 AM   #4
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
*x is "the contents of the pointer x"

&x is "the address of variable x"

Their statements are that each of these are the exact opposite of the other.

Their code examples, however confusing looking, explain:

*(&x) == x "If you take the contents of the address of a variable, you get the variable value."

&(*y) == y "If you take the address of the content of a pointer, you get the variable value"

The most fundamental things you should retain are the first two statements.

While the remainder is correct coding, it is not always seen.

Last edited by rtmistler; 01-02-2020 at 11:21 AM.
 
1 members found this post helpful.
Old 01-02-2020, 09:46 AM   #5
Geist
Member
 
Registered: Jul 2013
Distribution: Slackware 14 / current
Posts: 442

Rep: Reputation: 196Reputation: 196
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:
Code:
struct_pointer->value = new_value;
*struct_pointer.value = new_value;
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;
}

Last edited by Geist; 01-02-2020 at 10:06 AM.
 
Old 01-02-2020, 09:57 AM   #6
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,838

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
Quote:
Originally Posted by rtmistler View Post
*
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".
 
3 members found this post helpful.
Old 01-02-2020, 10:12 AM   #7
Geist
Member
 
Registered: Jul 2013
Distribution: Slackware 14 / current
Posts: 442

Rep: Reputation: 196Reputation: 196
Edit:
Damn, the website I referenced has errors. Nevermind.

Last edited by Geist; 01-02-2020 at 10:15 AM.
 
Old 01-02-2020, 10:34 AM   #8
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,572
Blog Entries: 19

Rep: Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451
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.
 
Old 01-02-2020, 11:35 AM   #9
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Just re-reviewing that original.

Reminding myself that, that information was not from official documentation, it was someone's answer.

The first bit of code is fine, I explained the logic of it, and I believe hazel just did so as well.

The second bit of code is not valid.
 
Old 01-02-2020, 11:40 AM   #10
hazel
LQ Guru
 
Registered: Mar 2016
Location: Harrow, UK
Distribution: LFS, AntiX, Slackware
Posts: 7,572
Blog Entries: 19

Rep: Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451Reputation: 4451
Quote:
Originally Posted by rtmistler View Post
Just re-reviewing that original.
The second bit of code is not valid.
Why not? It translates as "the address of the data stored at y is y". That seems true to me.
 
Old 01-02-2020, 01:07 PM   #11
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by hazel View Post
Why not? It translates as "the address of the data stored at y is y". That seems true to me.
Suggest you please show a compiled example using:
Code:
&(*y) == y
Here is a compiled answer for the first one:
Code:
*(&x) == x
Code:
#include <stdio.h>

void main(void)
{
    int x = 5;

    printf("Address of x: %p\nValue at address of x: %d\n", &x, *(&x));
}
Output:
Code:
Address of x: 0x7fff5c7b40c4
Value at address of x: 5
 
1 members found this post helpful.
Old 01-02-2020, 01:53 PM   #12
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,838

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
Code:
#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));
}
&(*y) [obviously] works only on pointers.
 
4 members found this post helpful.
Old 01-02-2020, 02:13 PM   #13
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Much obliged pan64. I agree, and started coding something similar, realizing that y had to be a pointer.

When I thought more about it, I felt that if y was not declared as a pointer, that the statement would be incorrect.

Per your final statement, you seem to agree.

Got hung up on that detail, and didn't code+test any further.
 
Old 01-03-2020, 05:04 AM   #14
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Original Poster
Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
Quote:
Originally Posted by hazel View Post
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 View Post
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)
 
Old 01-03-2020, 06:28 AM   #15
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Maybe you should perform some more tests. E.g.
Code:
/* 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;
}
example result (32-bit):
Code:
x=20200103
&x=ffd9ac8c
*(&x)=20200103
y=ffd9ac8c
&y=ffd9ac88
*(&y)=ffd9ac8c
&(*y)=ffd9ac8c
 
1 members found this post helpful.
  


Reply

Tags
address-of, c pointers, indirection



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Double-variable indirection in bash davelove Linux - Software 10 11-20-2011 08:13 AM
Indirection in class member declaration websinger Programming 8 09-08-2006 10:24 AM
bash parameter indirection possible? kornelix Programming 5 11-30-2005 08:35 AM
c++: ERROR: Invalid indirection ( post 2) ashirazi Programming 2 08-26-2004 10:15 AM
c++: ERROR: Invalid indirection ashirazi Programming 0 08-22-2004 12:09 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:04 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration