13

what is the difference between pointer , reference and dereference in c?

user615929
  • 475
  • 3
  • 7
  • 9
  • 5
    I don't understand the question. There are pointers in C, and you can dereference them, but there aren't references. That's a C++ thing. – David Thornley Feb 14 '11 at 18:35
  • 1
    @David: prior to C++ being published, there were references in C. C pointers are a kind of reference -- use of the unary `*` operator isn't called "dereferencing" for no reason. Once C++ was published and used the word "reference" for a different specific kind of reference, it became more difficult, since C clearly doesn't have those. – Steve Jessop Feb 14 '11 at 18:40

9 Answers9

29

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.

wilhelmtell
  • 57,473
  • 20
  • 96
  • 131
  • 1
    I get an error trying char& r = c: error: expected identifier or ‘(’ before ‘&’ token char& r = c; ^ – Tim Potapov Aug 08 '17 at 10:44
  • the question asked about C language specifically, but your answer has some C++ code concepts in it. char& r = c is a C++ thing – MartianMartian Sep 16 '18 at 14:53
8

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 value
    

    I've used a much smaller address size just for simplicity. Basically, 0x1111 is 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 0x1111 I look at 0x1112 and 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.

  • "A pointer is not a feature of C, it's a feature of x86 and its decendents and was deliberately added to the architecture to support C". What do you mean? The word "pointer" appears plenty of times in the C standard, how is it not a feature of C? How is it specific to x86 and not earlier architectures? In what sense was it added to x86 specifically to support C, and not to support in general the notion of addressable/indexable memory? – Steve Jessop Feb 14 '11 at 19:03
  • I don't think I know what I mean, I'm clearly chatting nonsense with that statement. Pointers are a feature of C and I believe x86 included them to work well with C. I think. Can't remember where I read that, but I'll leave that out of my answer since it adds nothing to it anyway. –  Feb 14 '11 at 19:08
6

There's no explicit reference type in C like in C++. Anywhere anybody says "reference" in context of C language you can assume a pointer.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
  • Agreed, make that assumption where it's plausible in context. On a quick check, it's also used in the C standard in a more general sense, to mean a requirement in one object file that a particular name be defined in another object file ("external references to functions and objects" in C89, and some mentions in C99 too). – Steve Jessop Feb 14 '11 at 18:44
  • Thanks @Steve, that's good to know, but I don't think OP was asking about this :) – Nikolai Fetissov Feb 14 '11 at 18:46
  • and even I didn't think it worth mentioning that's it's also used in the C standard to mean another document whose contents are relevant to C and mentioned in the standard (e.g. "ISO 31−11:1992, Quantities and units — Part 11: Mathematical signs and symbols for use in the physical sciences and technology."), and for mentions in one clause of the relevance of a later clause ("forward reference"). I think you're right what the question means :-) This is the one drawback of using English words to mean specific programming entities, you risk ambiguity with the English word... – Steve Jessop Feb 14 '11 at 18:48
2

Referencing means taking the address of an existing variable (using &) to set a pointer variable. In order to be valid, a pointer has to be set to the address of a variable of the same type as the pointer, without the asterisk:

int  c1;
int* p1;
c1 = 5;
p1 = &c1;
//p1 references c1

Dereferencing a pointer means using the * operator (asterisk character) to access the value stored at a pointer: NOTE: The value stored at the address of the pointer must be a value OF THE SAME TYPE as the type of variable the pointer "points" to, but there is no guarantee this is the case unless the pointer was set correctly. The type of variable the pointer points to is the type less the outermost asterisk.

int n1;
n1 = (*p1);

Invalid dereferencing may or may not cause crashes:

Any dereferencing of any uninitialized pointer can cause a crash Dereferencing with an invalid type cast will have the potential to cause a crash. Dereferencing a pointer to a variable that was dynamically allocated and was subsequently de-allocated can cause a crash Dereferencing a pointer to a variable that has since gone out of scope can also cause a crash. Invalid referencing is more likely to cause compiler errors than crashes, but it's not a good idea to rely on the compiler for this.

References:

http://www.codingunit.com/cplusplus-tutorial-pointers-reference-and-dereference-operators

& is the reference operator and can be read as “address of”.
* is the dereference operator and can be read as “value pointed by”.

http://www.cplusplus.com/doc/tutorial/pointers/

& is the reference operator    
* is the dereference operator

you can read wiki as well The dereference operator * is also called the indirection operator.

This text is taken from this link they have provided the same answer to the same question: meaning of "referencing" and "dereferencing"

Community
  • 1
  • 1
Habib Rehman
  • 590
  • 3
  • 15
  • 36
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – maskacovnik Aug 20 '15 at 06:54
  • you can say it without doing -1 the post. And i have changed it as you said – Habib Rehman Aug 20 '15 at 08:02
  • 1
    This is not mine -1, Your post is now clear, I give you +1, so your score will be 0 – maskacovnik Aug 20 '15 at 08:05
2

C has pointers and you can pretty much do anything you want with those pointers, you can deference them, and you change the value of a pointer. In fact pointer arithmetic is quite common technique in C programming. In my younger days as a C programmer references was not a commonly used term when talking with other C developers.

References as a term is very commonly used with Java, C# and Object Oriented Languages. In the context of Java and Object Oriented languages a reference is a pointer to an object instance in memory. With a reference you can't do pointer arithmetic, and that is the key difference between pointers and references in my view.

Pointers allow for pointer arithmetic and dereferencing, references only allow for dereferencing and changing what the reference points to.

ams
  • 60,316
  • 68
  • 200
  • 288
1

A pointer's value is a memory address.

int a;
int* b = &a;
// b holds the memory address of a, not the value of a.

A reference is a pointer with a value (memory address) that refers to a desired item.

int a;
int* b = &a;
// b is a reference to a.

A dereference is a technique of grabbing the memory contents that a pointer references.

int a;
int* b = &a;
int c = *b;
// c dereferences b, meaning that c will be set with the value stored in the address that b contains.

Note that a C++ reference is a different thing than a C reference. A C++ reference is an abstract idea where C++ decides to allow you to use non-pointer syntax for most calls, but will automatically "do the right thing" in passing a pointer when needed.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
0

as in "C++...":

In some cases, the compiler can optimize away a reference so that there is no object representing that reference at run-time.

4pie0
  • 29,204
  • 9
  • 82
  • 118
0

Pointer is an address of some data, e.g. int* a. Here a is really just the address where an int value is stored. A reference, in contrast, is another name for some variable, an alias, e.g. int a; int &b = a Here b is just another name for a: b++ has the same effect as a++.

grzkv
  • 2,599
  • 3
  • 26
  • 37
0

According to my experience, let me answer.

In C++, there are variables (normal variables, pointer variables, etc.) and references.

The compiler will assign an address to each variable. Obviously, the address of this variable cannot appear the same. It can be said that each variable is actually an address. What is the reference &, the reference is not a variable but a tag, so the compiler will not assign him an address, but it does not mean that it has no address, its address is the address of the variable or object it refers to, so it is used as a tag Used to set its address to the address of the variable or object it refers to when the compiler parses it. This creates a situation where the address is the same as the address of the variable or object it references, unbelief Can compile and ponder or try GDB!

Since the reference and the address of the object it refers to are the same, why should C++ introduce the concept of reference? The pointer can also achieve the goal, it is not an extra move. I say it's the main reason I think!

For consistency and consistency! for example:

class box {
 private:
  int l;

 public:
  box(int length = 0) : l(length){};
  box operator+(const box& that) {
    box b;
    b.l = this->l + that.l;
    return b;
  }
  box operator+(const box* that) {
    box b;
    b.l = this->l + that->l;
    return b;
  }
};

int main() {
  box b1(2);
  box b2(4);

  box b3 = b1 + b2;
  box b4 = b1 + &b2;

  return 0;
}

Above I overloaded the + operator of the box object, using references and pointers as arguments. In the main two expressions are not written in the same way, both can achieve the same function, obviously using the way of reference can be convenient to express, the use of pointers is more complicated, in the case of a large amount of code, you may be this Things get dizzy. If you think there are more important reasons, please let me know by comment!

Mr. Doubt
  • 1
  • 1