Java开发者疑问:C语言中变量与指针的区别及变量y的本质
作为从Java转过来接触C的开发者,刚碰指针的时候真的容易绕晕——我当初也踩过不少类似的坑,咱们一步步把这些问题掰扯清楚。
先搞明白:C语言里的普通变量 vs 指针
普通变量(比如你说的y)
当你写int y = 10;的时候,y其实是一块内存空间的"专属别名":编译器会在内存中划出一块适合存int类型的空间(通常是4字节),然后用y这个符号来指代它。你对y的所有操作,都是直接读写这块内存里的内容——这和Java里的基本类型(int、char)逻辑有点像,但Java把内存操作完全封装起来了,你根本感知不到地址的存在。
指针变量
而指针(比如int *x;)本身也是一个变量,但它的使命不是存普通的数据值,而是存另一个变量的内存地址。你可以把它理解成一个"内存路标":
- 操作指针本身(比如
x = &y;):是给这个路标换个指向,让它指向y的内存地址; - 操作指针指向的内容(比如
*x = 20;):是顺着路标找到对应的内存,然后修改里面的内容——这就是所谓的"间接访问"。
你的代码疑问:为什么改
y和*x会互相影响? 先还原一下你说的代码(应该是类似这样):
#include <stdio.h> int main() { int y = 20; int *x = &y; // &y是取y的内存地址,把这个地址存在指针x里 printf("*x = %d, y = %d\n", *x, y); // 输出:*x = 20, y = 20 y = 30; printf("*x = %d, y = %d\n", *x, y); // 输出:*x = 30, y = 30 *x = 40; printf("*x = %d, y = %d\n", *x, y); // 输出:*x = 40, y = 40 return 0; }
你的理解完全正确!y就是内存中某块固定位置的名称——一旦声明了int y,这块内存的位置就被确定下来(在程序运行期间,局部变量的位置可能会变,但逻辑上它就是绑定到y这个符号的)。当你把y的地址赋值给x后,*x就相当于通过地址去访问y对应的那块内存。所以不管是直接改y,还是通过*x间接修改,本质都是在操作同一块内存,结果自然会互相影响。
那
y和指针的定性差异是什么? 核心区别可以从这几点看:
- 本质身份不同:
y是数据存储容器,它的核心是"存数值",所有操作都是直接针对它里面的数值;- 指针(比如
x)是地址存储容器,它的核心是"存内存地址",主要作用是间接访问其他内存空间——更像一个"中介"。
- 操作逻辑不同:
- 对
y的操作是直接操作:y = 5;就是把5直接写入y对应的内存; - 对指针的操作分两种:
- 操作指针本身:
x = &z;——把指针的指向改成变量z的地址,这时候*x就和y没关系了; - 操作指向的内容:
*x = 5;——顺着指针的指向找到对应内存,修改里面的内容。
- 操作指针本身:
- 对
- 和Java的类比(帮你快速理解):
Java里没有指针,但可以用对象引用类比:比如String s = new String("hello");,s存的是对象的内存地址(Java不让你直接操作),你通过s操作对象,就像C里通过*x操作指向的变量。但要注意:Java的引用不能做地址运算(比如C里的x++让指针指向下一块内存),也不能随意转换指向,灵活性远不如C的指针。
内容的提问来源于stack exchange,提问作者blue note
相关产品推荐
相关产品推荐

