何时是数组名或函数名';转换为';变成指针?(C)中

何时是数组名或函数名';转换为';变成指针?(C)中,c,arrays,function,pointers,function-pointers,C,Arrays,Function,Pointers,Function Pointers,1)误解: 无论何时用C语言声明数组,都会隐式创建指向数组第一个元素(数组名称)的指针(是吗?我不这么认为!) 页面的前两行(尽管我不确定信息的正确性)说明了相同的情况 正如我们所看到的,当我们声明一个数组时,一个连续的内存块被分配给数组的单元,一个指针单元(适当类型)也被分配并初始化为指向数组的第一个单元。 但是当我输出包含在该指针中的地址和该指针的地址时,结果是相同的。 所以,我认为指针毕竟不是被创建的 2)我是从问题中学来的 在大多数情况下,数组名被转换为指针。 当编译器决定

1)误解:

  • 无论何时用C语言声明数组,都会隐式创建指向数组第一个元素(数组名称)的指针(是吗?我不这么认为!)

  • 页面的前两行(尽管我不确定信息的正确性)说明了相同的情况

    正如我们所看到的,当我们声明一个数组时,一个连续的内存块被分配给数组的单元,一个指针单元(适当类型)也被分配并初始化为指向数组的第一个单元。

  • 但是当我输出包含在该指针中的地址和该指针的地址时,结果是相同的。 所以,我认为指针毕竟不是被创建的

2)我是从问题中学来的

  • 在大多数情况下,数组名被转换为指针。
当编译器决定将数组名转换为指针时,谁能详细解释一下,为什么

PS:请解释相同的功能。同样在link中,给出了一个示例,说明对于函数
intsquare(int,int)
,任何
square
&square
*square
**square
都指向同一个函数指针。你能解释一下吗

编辑:代码段

int fruits[10];
printf("Address IN constant pointer is %p\n",  fruits);
printf("Address OF constant pointer is %p\n", &fruits); 
输出:

Address IN constant pointer is 0xbff99ca8
Address OF constant pointer is 0xbff99ca8

简短的回答是肯定的……除了有时。通常在声明数组后,每次使用其名称时,都会将其转换为指向数组对象的第一个元素的指针。但是,在某些情况下,这种情况不会发生。在@KeithThompson的回答中可以找到这些没有发生这种情况的案例


与数组类似,函数类型也将转换为指针值…有时除外。在@KeithThompson的回答中可以再次找到这种情况不再发生的情况

数组类型的表达式将隐式转换为指向数组对象的第一个元素的指针,除非它是:

  • 一元
    运算符的操作数
    
  • sizeof
    的操作数;或
  • 初始值设定项中的字符串文字,用于初始化数组对象
第三种情况的一个例子是:

char arr[6] = "hello";
“hello”
是一个数组表达式,类型为
char[6]
(5加1表示
'\0'
终止符)。它没有转换成地址;“hello”
的完整6字节值被复制到数组对象
arr

另一方面,在这方面:

char *ptr = "hello";
数组表达式
“hello”
“衰减”为指向
'h'
的指针,该指针值用于初始化指针对象
ptr
。(实际上应该是
const char*ptr
,但这是一个次要问题。)

函数类型的表达式(如函数名)将隐式转换为指向函数的指针,除非:

  • 一元
    运算符的操作数;或
  • sizeof
    sizeof function\u name
    的操作数非法,不是指针大小)
就这样

在这两种情况下,都不会创建指针对象。表达式被转换为(“衰减”为)指针值,也称为地址

(这两种情况下的“转换”与强制转换运算符指定的转换不同,它不是一种普通的类型转换。它不会像
int
-to-
float
转换那样,获取操作数的值并用它来计算结果的值。相反,数组或函数类型的表达式是“转换”的在编译时转换为指针类型的表达式。在我看来,“调整”一词比“转换”更清楚

请注意,数组索引运算符
[]
和函数调用“operator”
()
都需要指针。在像
func(42)
这样的普通函数调用中,函数名
func
将“衰减”为指向函数的指针,然后在调用中使用该指针。(只要函数调用做正确的事情,这种转换实际上不需要在生成的代码中执行。)

函数规则有一些奇怪的后果。在大多数上下文中,表达式
func
转换为指向函数
func
的指针。在
&func
中,
func
不会转换为指针,但
&
会生成函数的地址,即指针值。在
*func
中,
func
隐式转换为指针,然后
*
取消对它的引用以生成函数本身,然后(在大多数上下文中)将其转换为指针。在
**func
中,这种情况会重复发生

(C11标准草案指出数组还有另一个例外,即数组是新的
\u Alignof
运算符的操作数。这是草案中的一个错误,在最终发布的C11标准中已更正;
\u Alignof
只能应用于括号中的类型名,而不能应用于表达式。)

数组的地址及其第一个成员的地址:

int arr[10];
&arr;    /* address of entire array */
&arr[0]; /* address of first element */
是相同的内存地址,但类型不同。前者是整个数组对象的地址,类型为
int(*)[10]
(指向10
int
s数组的指针);后者的类型为
int*
。这两种类型不兼容(例如,您不能合法地将
int*
值分配给
int(*)[10]
对象),指针算法在这两种类型上的行为不同

有一条单独的规则规定,数组或函数类型的声明函数参数在编译时调整(未转换)为指针参数。例如:

void func(int arr[]);
这正是情商
void func(int *arr);
int fruits[10];
printf("Address IN constant pointer is %p\n",fruits);
printf("Address OF constant pointer is %p\n",&fruits); 
int fruits[10];
printf("Address IN constant pointer is %p\n", (void*)fruits);
printf("Address OF constant pointer is %p\n", (void*)&fruits);