简体   繁体   中英

Difference between a variable and a pointer in C (for java developer)?

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?

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 ).

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).

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

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

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`

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM