C 数组的标识符是否转换为指向数组的第一个元素或数组第一个元素的地址的指针?

Is the identifier of a C array converted to a pointer to the first element of the array or to the address of the first element of the array?

提问人:alessio solari 提问时间:7/28/2023 更新时间:7/28/2023 访问量:77

问:

一本 C 书说:“当数组标识符出现在表达式中时,标识符的类型从”T 数组“转换为”指向 T 的指针“,标识符的值将转换为指向数组第一个元素的指针”。

然而,C编程语言(由Kernighan和Ritchie)说“根据定义,数组类型的变量或表达式的值是数组中元素零的地址”。

  1. 那么,说“数组标识符转换为指向数组第一个元素的指针,或者数组标识符转换为第一个元素的地址”是否正确?

这让我有点困惑......

考虑这个小代码:

int a = 10;
&a;

2)&a是一般意义上的“指针”吗(即使一个指针在技术上是一个包含另一个变量地址的变量)?那么,一个对象的地址是否被认为是一般意义上指向该位置的“指针”,即使它没有被赋予指针变量?

3)如果我做类似((&a)+1)的事情,我在技术上是在做指针算术,所以它暗示&a在某种程度上是一个指针,不是吗?

C 指针内存 地址

评论

0赞 Ted Klein Bergman 7/28/2023
int* b = &a;所以是的,它是一个指针。godbolt.org/z/4h5G44KE8
0赞 Tom Karzes 7/28/2023
当数组转换为指针时,它是指向数组的第一个元素的指针。只要这样记住:元素的访问方式相同。所以你有 ,那么如果你传递给一个函数,它有 类型 .也是如此.但是,如果您采用地址,如 ,则它具有 类型 。它们是不同的类型,并且以不同的方式访问,即使它们引用相同的地址也是如此。int arr[10];arrint *arr + 0&arrint (*)[10]
0赞 alessio solari 7/28/2023
Tom Karzes,我怀疑地址是否被视为更大意义上的“指针”。例如,如果我有 int a = 10;&a 是更大意义上的“指针”吗?我想一定是因为我可以做指针算术,比如 (&a) + 1 。你觉得怎么样?
1赞 BadZen 7/28/2023
指针保存变量的地址。请记住,这是一个语义描述,编译器可以自由选择从不实际将该值存储在内存中,并且在许多情况下可能会选择不这样做。您可能会混淆“a”表示的 /variable/ 和“a”表示的 /value/。从技术上讲,该变量只是一个编译时对象。&aa
1赞 Tom Karzes 7/28/2023
@alessiosolari 在某些情况下,人们经常说数组“衰减”到指向其第一个元素的指针,尽管我认为该术语在 C 标准中不存在。但在其他上下文中,数组和指向其第一个元素的指针的行为不同,例如何时应用。sizeof

答:

2赞 Eric Postpischil 7/28/2023 #1

“指针”和“地址”在某种程度上可以互换使用。指向 X 的指针和 X 的地址大致相同。

当我们试图做出细微的区分时,我们可能会将“指针”区分为 C 语言中的对象,其值提供对对象或函数的引用,而“地址”作为告诉对象在内存中的位置的值。(地址还可以告诉函数在哪里,或者至少它的入口点在哪里,但这更复杂。“指针”还可用于引用与特定指针类型关联的地址。

在这个更精细的意义上,地址是指针的值,就像整数是 .尽管如此,我们通常对语言不太精确,指的是“3”而不是“值 3”。intintint

在大多数情况下,您可以将“指向数组第一个元素的指针”和“数组的第一个元素的地址”视为同一事物。

评论

0赞 Tom Karzes 7/28/2023
指针和地址之间的主要区别在于指针具有关联的数据类型,而地址则没有。因此,如果您有 ,两者都引用相同的地址,但它们的数据类型不同,因此它们的行为非常不同。int a[10];&a&a[0]
0赞 Andrew Henle 7/28/2023
指针”和“地址”在某种程度上可以互换使用。令人困惑。根据 C 标准,指针是保存地址的变量,该地址可能有效,也可能无效。所有数组都有一个地址。将地址和指针混为一谈是 IMO 的错误,而且经常这样做,这绝对令人困惑。
0赞 Eric Postpischil 7/28/2023
@AndrewHenle:Re “A pointer per the C standard is a variable that holds an address”: C 2018 6.3.2.3 1: “指向的指针可以转换为指向任何对象类型的指针,也可以从指向任何对象类型的指针转换。”由于转换的结果不是左值,因此指针的第二次使用不涉及任何变量。6.3.2.3 3 说“......如果将 null 指针常量转换为指针类型,则生成的指针(称为 null 指针)可以保证与指向任何对象或函数的指针进行比较。该地址可能只是 ,所以不是一个变量。该标准在“指针”的使用方面很灵活。void&x