[英]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
則會更改該內存的內容。 正確嗎? 如果是這樣,那么指針的質性區別是什么?
y
是int
類型的變量。 聲明后(在此示例中為初始化),編譯器會為其提供一個保存其值的內存地址。 分配給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/new
和free/delete
)。
簡單地說,從程序員的角度來看, 變量是具有指定大小的內存的命名區域。 該名稱僅在給定范圍內有效。
指針是在不知道該區域名稱的情況下引用內存區域(可能在某個地方定義了名稱)的手段。 通常將其描述為通過地址來指代該區域(盡管不一定表示其實際物理地址)。
int y = 1;
與許多此類語言一樣, y
是用值1初始化的int
類型的變量。請記住,變量是一個名稱,表示內存中的存儲(因此它是一個地址)。
int *x;
x
也是int *
類型的變量,通常稱為int
指針 。 可以存儲在這樣的變量中的值的類型是int
內存地址。 您可能將x
視為Java引用(至少在開始時如此)。
x = &y;
在這里x
分配了變量y
的地址值。 &y
表示的地址y
中C.所以x
指y
。
printf("%d\n",*x); // 1
這將打印1
,因為x
點y
包含1
。 *x
是一個C表達式,表示x
指向的變量的值 。 這稱為解引用 。
y = 2;
改變y
值的非常常見的賦值。
printf("%d\n",*x); // 2
因為*x
是x
指向的變量的值,所以它(當時)是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 variable
的address of a variable
。
間接或取消引用運算符*
給出指針所指向contents of an object
的contents 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.