C语言中&地址运算符是否返回指针?相关技术疑问解析
引用资料
IBM文档指出:“&(地址)运算符生成指向其操作数的指针。操作数必须是左值(lvalue)、函数指示符(function designator)或限定名称,不能是位域。”
微软说明:“一元取地址运算符(&)返回其操作数的地址(即指向操作数的指针)。取地址运算符的操作数可以是函数指示符或指代非位域对象的左值(lvalue)。”
诸多书籍提到:“地址运算符返回对象的地址。”
示例代码
int x = 10; &x; *(&x) = 20;
问题解答
1) &x是否只是一个int*类型的指针?
是的。在C语言的类型系统中,当&作用于int类型的左值x时,生成的结果就是int*(指向int的指针),这是语言标准明确规定的行为。
2) &x是否包含了它指向int类型的信息?我认为是的,因为编译代码并查看汇编代码时,我看到:
- movl $10, -4(%rbp)
- movl $20, -4(%rbp)
此处movl明显移动了4字节,对应int类型。
你的判断完全正确。&x作为int*类型,确实携带了指向类型的信息——这是C语言静态类型系统的核心特性之一:
- 编译阶段,编译器会根据
&x的int*类型,确定后续内存操作的宽度。比如执行*(&x) = 20时,会生成对应4字节的movl指令(匹配多数系统中int的大小);如果x是char类型,&x为char*,编译器会生成1字节的movb指令。 - 这种类型信息是编译期保留的,汇编阶段不会有“指针类型”的概念,但编译器会基于类型信息生成对应宽度的内存操作指令。
3) 既然不同资料有的说&a是地址,有的说是指针,是否能判定地址与指针完全等同?
不能,地址和指针是相关但完全不同的概念:
- 地址:是内存位置的纯数值标识(比如32位/64位整数),仅表示内存中的位置,不携带任何类型信息。
- 指针:是C语言中的数据类型,包含两个核心部分:一是内存地址的数值(即上面说的地址),二是指向对象的类型信息(编译期静态保留)。
资料中的不同表述是从不同角度描述同一结果:
- 说“返回地址”是从数值层面描述,指针的本质值就是操作数的内存地址;
- 说“生成指针”是从语言类型层面描述,
&运算符的结果是一个带类型的指针值。
举个直观例子:(void*)&x会把int*转换为void*,此时它仍然持有x的地址,但丢失了指向int的类型信息——这直接证明了地址(数值)和指针(带类型的地址)不是一回事。
内容的提问来源于stack exchange,提问作者alessio solari
相关产品推荐
相关产品推荐

