Here is a memory map; a representation of memory as a sequence of blocks:
address 01 02 03
+----+----+----+...
data within | 23 | 6f | 4a |
+----+----+----+...
Now suppose we create a character:
char c = 'z'; // 'z' is 7a in hex
Further suppose c is stored at address 01, so our memory looks like so:
address 01 02 03
+----+----+----+...
data within | 7a | 6f | 4a |
+----+----+----+...
Now, let's create a pointer:
char* p = &c; // point at c
p may be stored at address 02:
address 01 02 03
+----+----+----+...
data within | 7a | 01 | 4a |
+----+----+----+...
Here the pointer p is at address 02 and it points at address 01. That's the meaning of p = &c;. When we dereference the pointer p (at address 02) we look at what's in the address pointed at by p. That is, p points at address 01, and so dereferencing p means looking inside address 01.
Finally, lets create a reference:
char& r = c;
Here the memory layout doesn't change. That is, no memory is used to store r. r is a sort of alias for c, so when we refer to r we practically refer to c. r and c are conceptually one. Changing r means changing c, and changing c means changing r.
When you create a reference you must initialize, and once initialized you cannot re-initialize it with another target. That is, above the reference r means and forever will mean c.
Also related are const references. These are the same as a reference, except they are immutable:
const char& r = c;
r = 'y'; // error; you may not change c through r
c = 'y' // ok. and now r == 'y' as well
We use const references when we are interested in reading the data but frown upon changing it. By using a const reference the compiler will not copy the data, so this gives us ideal performance, but also forbid us from changing the data, for correctness.
In a sense, you can say that references are a compile-time feature, whereas pointers are a runtime feature. So references are faster and cheaper than pointers, but come with certain constraints and implications. Like other compile-time-vs-runtime alternatives, we sometimes pick one over the other for performance, sometimes for static analysis and sometimes for flexibility.
Answer from wilhelmtell on Stack OverflowHere is a memory map; a representation of memory as a sequence of blocks:
address 01 02 03
+----+----+----+...
data within | 23 | 6f | 4a |
+----+----+----+...
Now suppose we create a character:
char c = 'z'; // 'z' is 7a in hex
Further suppose c is stored at address 01, so our memory looks like so:
address 01 02 03
+----+----+----+...
data within | 7a | 6f | 4a |
+----+----+----+...
Now, let's create a pointer:
char* p = &c; // point at c
p may be stored at address 02:
address 01 02 03
+----+----+----+...
data within | 7a | 01 | 4a |
+----+----+----+...
Here the pointer p is at address 02 and it points at address 01. That's the meaning of p = &c;. When we dereference the pointer p (at address 02) we look at what's in the address pointed at by p. That is, p points at address 01, and so dereferencing p means looking inside address 01.
Finally, lets create a reference:
char& r = c;
Here the memory layout doesn't change. That is, no memory is used to store r. r is a sort of alias for c, so when we refer to r we practically refer to c. r and c are conceptually one. Changing r means changing c, and changing c means changing r.
When you create a reference you must initialize, and once initialized you cannot re-initialize it with another target. That is, above the reference r means and forever will mean c.
Also related are const references. These are the same as a reference, except they are immutable:
const char& r = c;
r = 'y'; // error; you may not change c through r
c = 'y' // ok. and now r == 'y' as well
We use const references when we are interested in reading the data but frown upon changing it. By using a const reference the compiler will not copy the data, so this gives us ideal performance, but also forbid us from changing the data, for correctness.
In a sense, you can say that references are a compile-time feature, whereas pointers are a runtime feature. So references are faster and cheaper than pointers, but come with certain constraints and implications. Like other compile-time-vs-runtime alternatives, we sometimes pick one over the other for performance, sometimes for static analysis and sometimes for flexibility.
Time to go on a term-bashing spree, because these things always cause confusion.
A pointer is a memory address in its own right. Cue fancy diagram for how it happens in memory:
| Address | Value | |----------|----------------| |0x1111 |0x1112 | <-- Pointer! |0x1112 |42 | <-- Pointed value |0x1113 |42 | <-- Some other valueI've used a much smaller address size just for simplicity. Basically,
0x1111is a pointer because its contents are the address of another value.Dereferencing means examining the value of the address held in the pointer's value. Such fancy language can be confusing; basically, if I dereference
0x1111I look at0x1112and get the value out of that address. Why? Because it's really useful and because assembly lets us do it too,mov rax, [r8]Is nasm/intel syntax for "look in r8, find that memory address, follow it and find the value at that memory address and put that in rax".
Pass by value. Pass by value means that when you create a function stack frame, which is the stack contents around a function, you copy every value that is an argument to wherever it goes. Registers, stack, wherever. Of course, if you copy a pointer's value, you're copying a memory address and thus creating another pointer pointing to the same memory. This is how functions like this:
void add(int* x) { *x = *x + 7; }Work.
Pass by reference. What that function above does is essentially pass by reference semantics as you will see them in say C++. The crucial and possibly only difference as the implementation is likely identical at the assembly level is that a reference is something the C++ compiler understands. Since the compiler is the language this is important. C understands pointers and manipulating memory, and so do C compilers, but they'll let you do whatever you like. You can't re-assign a reference, for example,
void cppadd(int& x) { int a = 7; x = &a; // doesn't work. }
So, to sum it up, references are on one level a language feature where the compiler understands where the source memory is and prevents modification of that source memory address. It understands you want to play with the value. Pointers are just that, memory addresses holding other memory addresses.
Wikipedia summarises it pretty well:
In the C++ programming language, a reference is a simple reference datatype that is less powerful but safer than the pointer type inherited from C. The name C++ reference may cause confusion, as in computer science a reference is a general concept datatype, with pointers and C++ references being specific reference datatype implementations.
Yes, I have mentioned C++ when this question is only C, but I feel it is prudent to clarify how a term has become somewhat confused with the addition of later languages.
I am absolutely confused on the topic of references vs pointers
Syntax for pointers and references - do you prefer to put the * or & on the variable name or data type?
C++ pointers and references
C++ Pointers and References : r/learnprogramming
Videos
On one hand, there is the Brief Introduction To C++’s Model For Type- And Resource-Safety which is considered to be an authoritative source for the obvious reason that Bjarne Stroustrup himself co-authored it, and it says :
"A reference is a restricted form of a pointer with some added syntactic sugar, so our techniques for pointers also deal with references."
On the other hand, there is the C++ FAQ which is also considered to be an authoritative source, and it says this about references:
"Important note: Even though a reference is often implemented using an address in the underlying assembly language, please do not think of a reference as a funny looking pointer to an object. A reference is the object, just with another name. It is neither a pointer to the object, nor a copy of the object. It is the object. There is no C++ syntax that lets you operate on the reference itself separate from the object to which it refers."
To me, it appears that these statements contradict each other, or do they? I don't know anymore. Could someone enlighten me and for once and for all, define exactly what a reference is, and what's the difference between that and a pointer? Thanks.