1

Coming from java, I'm confused as to why this works

int y = 1;
int *x;
x = &y;
printf(“%d\n”, *x); // 1
y = 2;
printf(“%d\n”, *x); // 2

What exactly is y? It seems to be a name for a constant location in memory, since reassigning it does change *x, and reassigning y changes the content of that memory. It that correct? And if so, what is the qualitative difference from a pointer?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
blue_note
  • 27,712
  • 9
  • 72
  • 90
  • 2
    Possible duplicate of [What are the differences between a pointer variable and a reference variable in C++?](https://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in) – Smit Ycyken Mar 10 '18 at 18:04
  • 1
    @SmitYcyken: not at all – blue_note Mar 10 '18 at 18:05
  • this dupe is too C++ for the question. And the question has the wrong C++ tag. – Jean-François Fabre Mar 10 '18 at 18:05
  • Reassigning `y` does change `*x` though? Define reassigning – Hatted Rooster Mar 10 '18 at 18:06
  • @SombreroChicken: that exactly is my question. why? – blue_note Mar 10 '18 at 18:07
  • 1
    But your question states "does not change `*x`", not "does change `*x`" – Hatted Rooster Mar 10 '18 at 18:07
  • there is exactly 1 integer slot in this example. Both `y` and `*x` share the same slot. – Jean-François Fabre Mar 10 '18 at 18:08
  • @SombreroChicken: you're right, sorry, edited – blue_note Mar 10 '18 at 18:08
  • 3
    a pointer _is_ a variable BTW. – Jean-François Fabre Mar 10 '18 at 18:09
  • @Jean-FrançoisFabre: I know, but I was talking about an `int x` variable – blue_note Mar 10 '18 at 18:10
  • a pointer adds an indirection to the access. – Jean-François Fabre Mar 10 '18 at 18:10
  • 2
    @Jean-FrançoisFabre A variable can hold a pointer, but I wouldn't say a variable *is* a pointer. – Cubic Mar 10 '18 at 18:10
  • A pointer is a variable that holds a memory address. – Smit Ycyken Mar 10 '18 at 18:11
  • 1
    In java, `Object o` is like `Object *o` in C. – Jean-François Fabre Mar 10 '18 at 18:11
  • An object reference in Java is a pointer ([§4.3.1](https://docs.oracle.com/javase/specs/jls/se9/html/jls-4.html#jls-4.3.1) for those wary), but C lets you do a lot more things with pointers than Java does, including making a pointer to a local `int` variable. Still, if you understand how Java object references work, then you're most of the way there with C pointers. Pointers let you modify memory which is located somewhere else in the program while (mostly) not caring about where that memory is actually located. – Radiodef Mar 10 '18 at 18:21
  • 2
    StackOverflow is not a teaching site. Did you bother reading a C guide to learn what a pointer is? – Andreas Mar 10 '18 at 18:22
  • @Andreas: yes, I did. Did you bother to read the question? I know what a pointer is, that's not what I'm asking – blue_note Mar 10 '18 at 18:26
  • @Radiodef: Thank you. I understand pointers, I don't understand variables. I thought they were values (like java primitives), but this shows they are more like references. So, if the name of the variable already points to memory, what is the qualitative difference from pointer? – blue_note Mar 10 '18 at 18:28
  • No, a *pointer* is like a Java reference. In Java, a variable can be a primitive or a reference. In C, a variable can be a type (primitive), a `struct`, a pointer, ... A C pointer is like a Java reference, but more powerful and a lot more dangerous. – Andreas Mar 10 '18 at 18:31
  • @Andreas: that's is my question. In most languages, variables are either references or values. here, in the case of `int y =5`, `y` is not a reference (because, as you said, pointers are references), neither a value (since it refers to a specific position in memory, not a specific value). So, what is it? – blue_note Mar 10 '18 at 18:34
  • 2
    Local variables work the same way as they do in Java. It's some temporary space allocated in the stack frame of the current thread which the value gets stored in. C just lets you take the address of the temporary space and refer to it using a pointer. Java doesn't have that kind of feature because it can lead to errors which cause security breaches. – Radiodef Mar 10 '18 at 18:42
  • All variables hold values. It the type of value that differs. In both Java and C, they can hold simple values, e.g. a number (`int`). The value can also be a reference/pointer to a "memory location". In Java, that memory location can only be an "object", and you cannot *manipulate" the reference value, just change it to refer to another object. In C, the memory location can be anywhere in memory, hence the danger of C pointers, and you can manipulate the pointer, e.g. make it point to the middle of an object or to program code. – Andreas Mar 10 '18 at 18:43
  • Since a C pointer can point *anywhere*, they can even point to the memory where a simple number (`int`) is stored. You can't do that in Java, since references may only point to objects. – Andreas Mar 10 '18 at 18:44
  • @Jean-FrançoisFabre Im keeping my eyes on you. – Hatted Rooster Mar 10 '18 at 19:23

6 Answers6

3

y is a variable of type int. Upon declaration(and initialization in this example) the compiler gives it a memory address that holds it's value. Assigning to y writes to that memory address and reading y reads that memory address.

x is a pointer to an int, in this case x points to the memory address of y meaning that *x will read any value that's in that memory address no matter how that value got there.

This means that:

*x = 5;

and

y = 5;

Both write to the same address and thus changes are visible for both y and *x since both read from that same address.


Since in java an int is an immutable object, the C equivalent of a Java int is a int* const in C, a constant pointer to an int.

If we have this in Java:

int a = 5;
int z = 3;
a = z;

The C equivalent would be:

/* int a = 5; */
int* a = malloc(sizeof(int)); // or `new` in C++
*a = 5;

/* int z = 3; */
int* z = malloc(sizeof(int));
*z = 3;

/* a = z; */
free(a); // or `delete` in C++
a = malloc(sizeof(int));
*a = *z;

We need pointers in C to reference other variables, in Java this feature is standard.

For example, let's say we have this Java class:

public class Foo
{
  public int x;
  public Foo()
  {
    x = 3;
  }
}

And now we use it like this:

Foo foo = new Foo();
foo.x = 5;

Foo foo2 = foo;
foo2.x = 10;
System.out.println(foo.x);

The result would be, as you know, 10. This is because the line:

Foo foo2 = foo;

Doesn't actually copy over the values of foo to foo2 as it's done in C-like languages but all it does is change where the reference is pointing to. In other words, foo can now change the state of foo2.


In C on the other hand, this isn't the standard behavior.

For example, let's say we have this struct:

typedef struct 
{
    int x;
} Foo;

And we use it like we used the class in the Java example:

Foo foo;
foo.x = 5;
Foo foo2;
foo2 = foo;
foo2.x = 10;

printf("%d", foo.x);

The output is 5 instead of 10. Huh? Why is that? Well, my friend, that's because C's "objects" by default are the actual objects, not references to memory of that object like in Java. This means that the line:

foo2 = foo;

Does a full memory copy and thus just copies over the values from one struct to the other. This means that changing foo2 will not change foo.


Okay, okay, but what if I want to change foo through foo2 then??

That's where pointers come in handy, we can just point to the memory address of foo:

Foo foo;
foo.x = 5;
Foo* foo2 = &foo;
foo2->x = 10;
printf("%d", foo.x);

Voila, you get your wanted 10 as you'd expect, just as in Java.

Every variable in Java (some exceptions apply) is a C pointer under the hood, the JVM just takes care of memory management for you (using malloc/new and free/delete).

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
  • does `y` always write to the same address assigned during it declaration? So, is it a named reference to a memory location? If so, why do we need pointers and references and variables? – blue_note Mar 10 '18 at 18:23
  • @blue_note Yes it does. And no, it's not a named reference to a memory location, it _is_ the memory location. A pointer is a named reference to a memory location in that it can hold the address of a memory location. Referring to `y` is the same as referring to `0xDEADBEEF` or whatever memory address it was given. – Hatted Rooster Mar 10 '18 at 18:23
  • @blue_note No programmer is going to remember memory addresses though so they use variable names to refer to the address. Variable names are only helpers for programmers, at assembly level, when the compiler has done its job, there is no concept of variable names, only addresses (unlike Java byte code) – Hatted Rooster Mar 10 '18 at 18:28
  • So, the name is like a `final` reference in java? even for primitives? – blue_note Mar 10 '18 at 18:38
  • @blue_note Kind of.. in Java an `int` is immutable so reassigning them creates a new object and makes it point to that new object, then it destroys the previous one. In C and C++ an `int` is the actual object, the name `y` is not pointing to some memory, it _is_ the memory. – Hatted Rooster Mar 10 '18 at 18:41
1

Simplistically, from the programmer's point of view, a variable is a named region of memory with a specified size. The name is only valid within a given scope.

A pointer is the means to refer to a region of memory (perhaps somewhere defined with a name), without knowing the name of that region. This is commonly described as referring to the region by its address (although it doesn't necessarily mean its actual physical address).

Mark Benningfield
  • 2,800
  • 9
  • 31
  • 31
1
int y = 1;

As in many such languages, y is a variable of type int initialized with value 1. Remind that a variable is a name denoting a storage in memory (so it as an address).

int *x;

x is also a variable of type int *, which is usually named pointer to int. The kind of values that can be stored in such a variable are memory addresses of int. You may think of x as a Java reference (at least at the beginning).

x = &y;

Here x is assigned with the value of address of variable y. &y means address of y in C. So x refers to y.

printf("%d\n",*x); // 1

That prints 1 because x points to y that contains 1. *x is a C expression to say value of variable pointed by x. It is called dereferencing.

y = 2;

Very common assignment to change the value of y.

printf("%d\n",*x); // 2

As *x is the value of variable pointed by x, it is (at that time) the value of y, then 2.

A schema could be:

+---------+                  +-----+
|      ---|----------------->|     |
+---------+                  +-----+
     x                          y
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
0

First of all what is a pointer in C and C++. Pointer is just like any other variables in C and C++ but only difference is a pointer variable can hold the address of another variable. Now in your case

int y = 1;// y is assigned with value 1
int *x;// x is a pointer variable of type int so that it can store the address of an int variable
x = &y;// now you have assign the address of variable y in x
printf(*x); // 1. As x is holding the address of y where you have assign value 1 so *x (dereference of a pointer) will get the value stored in address of y
y = 2;// you change the value of y to 2
printf(*x); // 2. As x is holding the address of y so dereferencing of *x will print the value against that address and address is y's address hence value it will print of y i.e. 2

Also if you do like this:-

*x = 7; // assign 7 in the address that x is pointing to 
printf("%d\n", y);// will print 7

int z = 10;
x = &z; // now x is pointing at z and no longer pointing at y
printf("%d\n", *x);// will print 10
Abhijit Pritam Dutta
  • 5,521
  • 2
  • 11
  • 17
0

What exactly is y?

y is a variable of integer type and you have assigned value 1 to it.

A pointer is a variable which contains the address in memory of another variable. We can have a pointer to any variable type.

The unary or monadic operator & gives the address of a variable.

The indirection or dereference operator * gives the contents of an object pointed to by a pointer.

To declare a pointer to a variable write:

   int *pointer_name;

In your case

int y = 1;   // int type variable initialized to 1
int *x;      // a pointer to int object

x = &y;      // now pointer `x` has a value assigned, it holds the address of variable `y` 

Pointer x holds the address of the variable y.

printf("%d\n",*x);  // 1 - prints the value of `y`
y = 2;              // value of `y` has changed to `2`     
printf("%d\n",*x);  // 2 - prints the value of `y`
sg7
  • 6,108
  • 2
  • 32
  • 40
0

x only holds address of y so whenever you called *x it prints whatever value is stored on this address. if you try x = &y; printf(x); // 1 y = 2; printf(x); you find same answer in both cases because address of y is same in both cases only value is being changed.

Rohit Upadhyay
  • 123
  • 1
  • 8