簡體   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