C 数组指针的自动类型转换

C 数组指针的自动类型转换,c,arrays,pointers,C,Arrays,Pointers,我试图通过以下程序理解指针和数组 #include <stdio.h> int main(void) { int arr[] = {1, 2, 3, 4, 5}; int *ptr = &arr; int *ptr1 = arr; int (*ptr2)[5] = &arr; int (*ptr3)[5] = arr; int *ptr4 = &arr[0]; int (*ptr5)[5] = &

我试图通过以下程序理解指针和数组

#include <stdio.h>

int main(void) {
    int arr[] = {1, 2, 3, 4, 5};
    int *ptr = &arr;
    int *ptr1 = arr;
    int (*ptr2)[5] = &arr;
    int (*ptr3)[5] = arr;
    int *ptr4 = &arr[0];
    int (*ptr5)[5] = &arr[0]; 
    printf("%d %d %d %d %d %d\n",*(ptr+1), *(ptr1+1), *(ptr2+1), 
            *(ptr3+1), *(ptr4+1), *(ptr5+1));
    return 0;
}
#包括
内部主(空){
int arr[]={1,2,3,4,5};
int*ptr=&arr;
int*ptr1=arr;
int(*ptr2)[5]=&arr;
int(*ptr3)[5]=arr;
int*ptr4=&arr[0];
int(*ptr5)[5]=&arr[0];
printf(“%d%d%d%d%d%d%d\n”)、*(ptr+1)、*(ptr1+1)、*(ptr2+1),
*(ptr3+1),*(ptr4+1),*(ptr5+1));
返回0;
}
在前面的一个问题中,我了解到
arr
是指向第一个元素的指针,其中as
&arr
是指向整个数组的指针

如果我们在上面的程序中对
ptr
ptr1
进行指针运算,它们都会产生相同的结果,即它们都是指向整数的指针,因为它们被分配给
int*
类型的变量

但是,我创建了一个指向5个元素数组的指针
ptr2
,并指定了&arr的值。如果我尝试增加ptr2,它将按预期增加5个元素。在
ptr3
ptr4
ptr5

[编辑]当我执行
int*ptr=&arr
时,指向数组的指针会自动类型转换为
int*

我可以假定
&arr,arr,&arr[0]
表达式实际上是相同的,因为它们产生相同的值吗?这个值的算术实际上取决于指定变量的类型?

不,
&arr
arr
&arr[0]
是不同的。详细说明,

  • &arr
    是指向整个数组的指针。为了更好地理解,您可以参考数据类型
    &arr
    在这里是
    int(*)[5]
    类型,即指向5
    int
    s数组的指针

  • arr
    是数组名,在某些情况下,它会衰减到指向数组第一个元素的指针

  • &arr[0]
    在任何情况下都是数组第一个元素的地址
建议:启用所有编译器警告,它会告诉您哪里出了问题

那么根据上述的理解,

 int *ptr = &arr;
是错误的,因为它们不是兼容类型。同样的道理也适用于

int (*ptr5)[5] = &arr[0];

因此,您尝试使用这些变量执行的任何操作(以及它们的结果,如果有的话)都没有定义。

否,&arr和arr在C中不同,因为arr是指向arr的第一个元素的指针,&arr是指向arr本身的指针。然而,arr和&arr[0]的行为是相同的,因为它们都指向数组的第一个元素(仍然不完全相同)。换句话说,您可以理解isarr和&arr[0]指向4字节位置,而&arr指向5x4字节位置,因此它们是不同的。
int*ptr=&arr使用ptr是未定义的行为。这同样适用于
int(*ptr3)[5]=arr
int(*ptr5)[5]=&arr[0]
只是说说而已。你的意思是说,它没有在标准中定义吗?@RaviChandra不,他的意思是说列出的操作的结果无法预测,因此是未定义的。@RaviChandra undefined behavior在C(和其他语言标准)中指的是一个非常特殊的东西。简而言之,这意味着当程序中存在未定义的行为时,无法预测程序的任何行为。它不再是有效的C。编译器可以做任何事情。@RaviChandra如果不忽略警告,就会发生这种情况: