简体   繁体   English

C语言中的变量和指针之间的区别(对于Java开发人员)?

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

Coming from java, I'm confused as to why this works 来自Java,我对此感到困惑

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

What exactly is y ? 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. 它似乎是内存中恒定位置的名称,因为重新分配确实会更改*x ,而重新分配y则会更改该内存的内容。 It that correct? 正确吗? And if so, what is the qualitative difference from a pointer? 如果是这样,那么指针的质性区别是什么?

y is a variable of type int . yint类型的变量。 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. 分配给y写入该内存地址,而读取y则会读取该内存地址。

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. x是一个指向int的指针,在这种情况下, x指向y的内存地址,这意味着*x将读取该内存地址中的任何值,无论该值如何到达那里。

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. 两者都写入相同的地址,因此y*x均可见更改,因为两者均从同一地址读取。


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 . 由于在java中int是不可变的对象,因此Java int的C等效项是C中的int* const ,它是指向int的常量指针。

If we have this in Java: 如果我们在Java中有这个:

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

The C equivalent would be: C等效项为:

/* 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. 我们需要C语言中的指针来引用其他变量,在Java中此功能是标准的。

For example, let's say we have this Java class: 例如,假设我们有这个Java类:

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 . 如您所知,结果将是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. 实际上并不像在C语言中那样将foo的值复制到foo2 ,但是它所做的只是更改引用指向的位置。 In other words, foo can now change the state of foo2 . 换句话说, foo现在可以更改foo2的状态。


In C on the other hand, this isn't the standard behavior. 另一方面,在C语言中,这不是标准行为。

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: 我们像在Java示例中使用类一样使用它:

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

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

The output is 5 instead of 10 . 输出是5而不是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. 好吧,我的朋友,这是因为默认情况下C的“对象”是实际的对象,而不是像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 . 这意味着更改foo2不会更改foo


Okay, okay, but what if I want to change foo through foo2 then?? 好的,好的,但是如果我想将foo更改为foo2呢?

That's where pointers come in handy, we can just point to the memory address of foo : 这就是指针派上用场的地方,我们只需指向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. 瞧,就像Java中一样,您可以得到想要的10

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 ). Java中的每个变量(都有一些例外情况)在幕后都是C指针,JVM只是为您处理内存管理(使用malloc/newfree/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). 与许多此类语言一样, y是用值1初始化的int类型的变量。请记住,变量是一个名称,表示内存中的存储(因此它是一个地址)。

int *x;

x is also a variable of type int * , which is usually named pointer to int . x也是int *类型的变量,通常称为int指针 The kind of values that can be stored in such a variable are memory addresses of int . 可以存储在这样的变量中的值的类型是int内存地址。 You may think of x as a Java reference (at least at the beginning). 您可能将x视为Java引用(至少在开始时如此)。

x = &y;

Here x is assigned with the value of address of variable y . 在这里x分配了变量y的地址值。 &y means address of y in C. So x refers to y . &y表示的地址y中C.所以xy

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

That prints 1 because x points to y that contains 1 . 这将打印1 ,因为xy包含1 *x is a C expression to say value of variable pointed by x . *x是一个C表达式,表示x指向的变量的值 It is called dereferencing . 这称为解引用

y = 2;

Very common assignment to change the value of y . 改变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 . 因为*xx指向的变量的值,所以它(当时)是y的值,然后是2

A schema could be: 模式可以是:

+---------+                  +-----+
|      ---|----------------->|     |
+---------+                  +-----+
     x                          y

First of all what is a pointer in C and C++. 首先,C和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. 指针与C和C ++中的任何其他变量一样,但是唯一的区别是指针变量可以保存另一个变量的地址。 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是什么?

y is a variable of integer type and you have assigned value 1 to it. y是整数类型的变量,并且您已为其分配值1

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 . 一元或一元运算符&给出address of a variableaddress of a variable

The indirection or dereference operator * gives the contents of an object pointed to by a pointer. 间接或取消引用运算符*给出指针所指向contents of an objectcontents of an object

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 . 指针x保存变量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. x仅保存y的地址,因此无论何时调用* x,它都会打印此地址上存储的任何值。 if you try x = &y; 如果您尝试x =&y; printf(x); printf(x); // 1 y = 2; // 1 y = 2; printf(x); printf(x); you find same answer in both cases because address of y is same in both cases only value is being changed. 在这两种情况下,您都会找到相同的答案,因为在两种情况下,y的地址都相同,仅更改值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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