繁体   English   中英

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

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

来自Java,我对此感到困惑

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

y是什么? 它似乎是内存中恒定位置的名称,因为重新分配确实会更改*x ,而重新分配y则会更改该内存的内容。 正确吗? 如果是这样,那么指针的质性区别是什么?

yint类型的变量。 声明后(在此示例中为初始化),编译器会为其提供一个保存其值的内存地址。 分配给y写入该内存地址,而读取y则会读取该内存地址。

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

这意味着:

*x = 5;

y = 5;

两者都写入相同的地址,因此y*x均可见更改,因为两者均从同一地址读取。


由于在java中int是不可变的对象,因此Java int的C等效项是C中的int* const ,它是指向int的常量指针。

如果我们在Java中有这个:

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

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;

我们需要C语言中的指针来引用其他变量,在Java中此功能是标准的。

例如,假设我们有这个Java类:

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

现在我们像这样使用它:

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

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

如您所知,结果将是10 这是因为行:

Foo foo2 = foo;

实际上并不像在C语言中那样将foo的值复制到foo2 ,但是它所做的只是更改引用指向的位置。 换句话说, foo现在可以更改foo2的状态。


另一方面,在C语言中,这不是标准行为。

例如,假设我们具有以下结构:

typedef struct 
{
    int x;
} Foo;

我们像在Java示例中使用类一样使用它:

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

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

输出是5而不是10 ?? 这是为什么? 好吧,我的朋友,这是因为默认情况下C的“对象”是实际的对象,而不是像Java中那样引用该对象的内存。 这意味着该行:

foo2 = foo;

执行完整的内存复制,因此仅将值从一个结构复制到另一个结构。 这意味着更改foo2不会更改foo


好的,好的,但是如果我想将foo更改为foo2呢?

这就是指针派上用场的地方,我们只需指向foo的内存地址即可:

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

瞧,就像Java中一样,您可以得到想要的10

Java中的每个变量(都有一些例外情况)在幕后都是C指针,JVM只是为您处理内存管理(使用malloc/newfree/delete )。

简单地说,从程序员的角度来看, 变量是具有指定大小的内存的命名区域。 该名称仅在给定范围内有效。

指针是在不知道该区域名称的情况下引用内存区域(可能在某个地方定义了名称)的手段。 通常将其描述为通过地址来指代该区域(尽管不一定表示其实际物理地址)。

int y = 1;

与许多此类语言一样, y是用值1初始化的int类型的变量。请记住,变量是一个名称,表示内存中的存储(因此它是一个地址)。

int *x;

x也是int *类型的变量,通常称为int指针 可以存储在这样的变量中的值的类型是int内存地址。 您可能将x视为Java引用(至少在开始时如此)。

x = &y;

在这里x分配了变量y的地址值。 &y表示的地址y中C.所以xy

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

这将打印1 ,因为xy包含1 *x是一个C表达式,表示x指向的变量的值 这称为解引用

y = 2;

改变y值的非常常见的赋值。

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

因为*xx指向的变量的值,所以它(当时)是y的值,然后是2

模式可以是:

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

首先,C和C ++中的指针是什么。 指针与C和C ++中的任何其他变量一样,但是唯一的区别是指针变量可以保存另一个变量的地址。 现在你的情况

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

另外,如果您这样做:

*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

y是什么?

y是整数类型的变量,并且您已为其分配值1

指针是一个变量,其中包含另一个变量在内存中的地址。 我们可以有一个指向任何变量类型的指针。

一元或一元运算符&给出address of a variableaddress of a variable

间接或取消引用运算符*给出指针所指向contents of an objectcontents of an object

要声明指向变量的指针,请执行以下操作:

   int *pointer_name;

就你而言

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` 

指针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仅保存y的地址,因此无论何时调用* x,它都会打印此地址上存储的任何值。 如果您尝试x =&y; printf(x); // 1 y = 2; printf(x); 在这两种情况下,您都会找到相同的答案,因为在两种情况下,y的地址都相同,仅更改值。

暂无
暂无

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

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