地址用于标识一个固定大小的存储空间,通常为每个字节,作为一个整数。这被精确地称为字节地址,它也被ISO c使用。可以有一些其他方法来构造地址,例如为每一位。然而,只有字节地址是如此经常使用,我们通常省略“字节”。
从技术上讲,一个地址在C中从来都不是一个值,因为在(ISO) C中术语“值”的定义是:
对象的内容在解释为具有特定类型时的精确含义
(我强调了一下。)然而,在C语言中没有这样的“地址类型”。
指针不一样。指针是C语言中的一种类型。有几种不同的指针类型。它们不一定遵守相同的语言规则集,例如++对int*类型值和char*类型值的影响。
C语言中的值可以是指针类型。这叫做指针值。需要明确的是,指针值在C语言中不是指针。但是我们习惯把它们混在一起,因为在C语言中,它不太可能是模棱两可的:如果我们把表达式p称为“指针”,它只是一个指针值,而不是一个类型,因为C语言中的命名类型不是由表达式表示,而是由type-name或typedef-name表示。
其他一些事情是微妙的。作为C语言的使用者,首先要知道object是什么意思:
数据存储在执行环境中的区域,其中的内容可以表示
值
对象是表示特定类型的值的实体。指针是一种对象类型。因此,如果我们声明int* p;,则p表示“指针类型的对象”,或“指针对象”。
Note there is no "variable" normatively defined by the standard (in fact it is never being used as a noun by ISO C in normative text). However, informally, we call an object a variable, as some other language does. (But still not so exactly, e.g. in C++ a variable can be of reference type normatively, which is not an object.) The phrases "pointer object" or "pointer variable" are sometimes treated like "pointer value" as above, with a probable slight difference. (One more set of examples is "array".)
由于指针是一种类型,而地址在C语言中实际上是“无类型的”,因此指针值大致“包含”一个地址。指针类型的表达式可以产生一个地址,例如。
Iso c11 6.5.2.3
一元&操作符产生其操作数的地址。
请注意,这个措辞是由WG14/N1256引入的,即ISO C99:TC3。在C99中有
一元&操作符返回其操作数的地址。
它反映了委员会的观点:地址不是由一元操作符&返回的指针值。
尽管有上述措辞,但即使在标准上也存在一些混乱。
Iso c11 6.6
地址常量是一个空指针,一个指向左值的指针,该左值指定一个static对象
存储持续时间,或指向函数指示符的指针
Iso c++ 11 5.19
3.一个地址
常量表达式是指针类型的prvalue核心常量表达式,计算结果为对象的地址
具有静态存储持续时间的对象,转换为函数的地址、空指针值或prvalue核心
类型std::nullptr_t. ...的常量表达式
(最近的c++标准草案使用了另一种措辞,所以不存在这个问题。)
实际上,C中的“地址常量”和c++中的“地址常量表达式”都是指针类型的常量表达式(或者至少从c++ 11开始是“类指针”类型)。
内置的一元&运算符在C和c++中被称为“address-of”;类似地,std::addressof是在c++ 11中引入的。
这些命名可能会带来误解。结果表达式是指针类型的,所以它们被解释为:结果包含/产生一个地址,而不是一个地址。