数组如何像C中的指针一样工作?

数组如何像C中的指针一样工作?,c,C,我知道这个问题已经被回答了好几次,但我无法理解下面的脚本。顺便说一句,我对C不熟悉 正如我得到的,如果数组用作值,它表示第一个字符的地址,也就是指针 如果我运行这个: int main (){ char quote[] = "C is great" printf ("The quote: %s\n",quote); printf ("The address of quote is %p\n",quote); printf ("Size of quote is %lu\n",siz

我知道这个问题已经被回答了好几次,但我无法理解下面的脚本。顺便说一句,我对C不熟悉

正如我得到的,如果数组用作值,它表示第一个字符的地址,也就是指针

如果我运行这个:

int main (){
  char quote[] = "C is great"
  printf ("The quote: %s\n",quote);
  printf ("The address of quote is %p\n",quote);
  printf ("Size of quote is %lu\n",sizeof(quote));
}
我得到:

The quote: C is great
The address of quote is 0x7fff06fa0d90
Size of quote is 11
所以我的问题是在所有printf情况下,我都使用了相同的变量quote,但是通过改变print类型,它如何从值变为指针,指针表示形式存储在哪里,因为sizeof给出了字符串的长度

printf ("The quote: %s\n",quote);

谢谢

指针表示未存储在指定位置。它与
2+2
的结果具有相同的“存储”。(通常,这将是一个登记册)。这些在C中被正式称为值;有时出于讨论目的而称为右值

在这两种情况下都会发生转换,您将
quote
作为
printf
的参数。
%s
%p
告诉printf是输出接收到的指针的表示,还是跟随该指针并打印出另一端的字符


只要需要,就会形成右值。
sizeof
运算符不会对其操作数执行左值到右值的转换,因此
sizeof(引号)
不会对指针生成或执行任何操作。

数组类型到指针类型的转换有一些例外

C11:6.3.2.1(p3): 除非它是
sizeof
运算符的操作数、
\u Alignof
运算符或一元
&
运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为“array of type”的表达式将转换为类型为“pointer to type”的表达式它指向数组对象的初始元素,不是左值

请注意,该声明

printf ("The address of quote is %p\n",quote);  
打印
quote
的第一个元素的地址,而不是
quote
的地址,尽管打印
quote
的地址时会得到相同的地址值



请注意,草稿中提到的
\u Alingof
是一个错误。

在内部,指针是一个包含地址的整数值。因此,在所有情况下,您都将此指针值传递给
printf()


但是格式说明符决定了
printf()
将如何处理该指针。在一种情况下,它读取指针中包含的地址处的字符。在另一种情况下,它只打印指针值。

所有变量都是指向C中内存位置的指针。除此之外没有其他内容。编译器通过指针跟踪变量。它还跟踪变量的类型和大小,但这些并不严格。每个变量都保证有一个指针,但类型和大小可以更改

类型和大小决定了在程序中使用变量时所表示的值,但就您的程序而言,它实际上不知道每个指针上存储的是什么,除非编译器专门将其写入编译后的程序中

您可以使用强制转换来重写类型(如果不小心,甚至读取内存超出范围)。例如,如果您有一个12个字符的数组,您可以根据需要将值读取为3个整数的数组

对于静态数组(如您的示例),当您定义数组的大小或将值分配给数组时,编译器会分配所需的内存

它知道长度,要么是因为您在定义中明确地告诉了它(
char quote[11]
),要么是因为它知道数组中存储了什么(
“C很棒”
=10)。因为char类型变量是1字节,所以其中10个变量必须是10字节

您的数组实际上是11个字节。这是因为您分配给它的方式和内容。在C语言中,当编译器找到字符串文字时,它会自动在末尾附加一个
NULL
char。如果不这样做,像
printf
这样的函数将不知道字符串的长度。它不知道,因为大小和类型没有与变量一起存储

如果将数组编写为:

char quote[] = {'C',' ','i','s',' ','g','r','e','a','t'};
编译器不会知道它是一个字符串,而数组是10字节而不是11字节。在本例中,当您尝试将
printf
作为字符串时,它的行为也可能会异常,因为
printf
依赖
NULL
字节来知道它何时到达字符串的末尾

printf ("The quote: %s\n",quote);

查看“数组衰减”()-在声明数组的作用域/上下文中,编译器可以获得有关数组长度的信息,但当作为指针(例如,作为函数参数)传递时信息丢失。
%p
的输出是由实现定义的。数组的行为不像指针-在许多情况下,它们被转换为指向其第一个元素的指针。“数组如何像C中的指针?”——决不是。数组充当数组,指针充当指针,数组几乎总是隐式转换为指向其第一个元素的指针,除非它是
&
sizeof
运算符的操作数。请使用
%zu
而不是
%p
来打印内存地址,这里提到的是草案中的一个错误。数组不能是
\u Alignof
的操作数,语法为
\u Alignof(类型名称)