c中的数组名到底是什么?

c中的数组名到底是什么?,c,arrays,pointers,memory-address,C,Arrays,Pointers,Memory Address,我很难理解C中数组名称的类型和用法。这可能是一篇很长的文章,但请耐心听我说 我理解以下语句声明a为int[]类型,即整数数组 int a[30]; 而a也指向数组的第一个元素,像*(a+2)这样的东西是有效的。因此,使a看起来像指向整数的指针。但是实际上int[]和int*的类型是不同的;前者是数组类型,后者是指向整数的指针 int a[30]; 当传递给函数时,类型为int[]的变量也会转换为类型为int*的变量;正如在C中一样,数组是通过引用传递的(除了sizeof操作符) 这一点让我心

我很难理解C中数组名称的类型和用法。这可能是一篇很长的文章,但请耐心听我说

我理解以下语句声明
a
int[]
类型,即整数数组

int a[30];
a
也指向数组的第一个元素,像
*(a+2)
这样的东西是有效的。因此,使
a
看起来像指向整数的指针。但是实际上
int[]
int*
的类型是不同的;前者是数组类型,后者是指向整数的指针

int a[30];
当传递给函数时,类型为
int[]
的变量也会转换为类型为
int*
的变量;正如在
C
中一样,数组是通过引用传递的(除了
sizeof
操作符)

这一点让我心神不定。请查看以下代码:

int main()
{
    int (*p)[3];
    int a[3] = { 5, 4, 6 };

    p = &a;

    printf("a:%d\t&a:%d\n",a,&a);
    printf("%d",*(*p + 2));
}
输出:

a:2686720       &a:2686720
6
那么,上面的代码是如何工作的呢?我有两个问题:

  • a
    &a
    具有相同的值。为什么?
  • 什么是
    int(*p)[3]做什么?它声明了一个指向数组的指针,我知道这一点。但是,指向数组的指针与指向数组第一个元素的指针和数组的名称有何不同
  • 有人能澄清一下吗?我有很多困惑

    我知道我应该使用
    %p
    作为占位符,而不是使用
    %d
    来打印指针变量的值。因为使用整数占位符可能会打印截断的地址。但我只想让事情简单一些

  • a对应于指向数组第0个元素的指针。而&a的情况也是如此,它只给出了数组的起始地址
  • 作为指向数组a[]起始元素的-->指针,它不知道其他元素的位置。

    &用于存储数组a[]的一个-->地址位置,它存储第一个元素位置,但知道每个元素的位置

    类似地,其他元素的位置将是(a+2),(a+4)等等,直到阵列的末端

    因此,你得到了这样的结果

  • int(*p)[3]是指向数组的指针。如果它是int*p[3],它的意思就完全不同了。这意味着一个指针数组,与此上下文完全不同
  • 指向数组的指针将自动处理所有其他数组 数组中的元素。在本例中,您的为(p)

    然而,指向数组第一个元素的指针,即will 只知道数组的第一个元素。您必须手动 给出访问下一个元素的指针算术方向。请参见本节中的 case--我们可以通过在a上加2得到a的第二个元素,即。 a+2,第三个元素,将4添加到a,即a+4,依此类推当心 二的差,因为它是一个整数数组

  • a对应于指向数组第0个元素的指针。而&a的情况也是如此,它只给出了数组的起始地址
  • 作为指向数组a[]起始元素的-->指针,它不知道其他元素的位置。

    &用于存储数组a[]的一个-->地址位置,它存储第一个元素位置,但知道每个元素的位置

    类似地,其他元素的位置将是(a+2),(a+4)等等,直到阵列的末端

    因此,你得到了这样的结果

  • int(*p)[3]是指向数组的指针。如果它是int*p[3],它的意思就完全不同了。这意味着一个指针数组,与此上下文完全不同
  • 指向数组的指针将自动处理所有其他数组 数组中的元素。在本例中,您的为(p)

    然而,指向数组第一个元素的指针,即will 只知道数组的第一个元素。您必须手动 给出访问下一个元素的指针算术方向。请参见本节中的 case--我们可以通过在a上加2得到a的第二个元素,即。 a+2,第三个元素,将4添加到a,即a+4,依此类推当心 二的差,因为它是一个整数数组

  • a和&a有相同的值。如何
  • 它们的值相同,但类型不同。数组对象在元素之间(之前或之后)没有填充,因此数组的地址和数组的第一个元素的地址是相同的

    即:

    (void *) a == (void *) &a
    
  • 它到底做什么int(*p)[3];声明指向数组的指针,我知道这一点。但是,指向数组的指针与指向数组第一个元素和数组名称的指针有何不同
  • 这是两种不同的指针类型。例如,指针算法:

    a + 1   /* address of the second element of the array */
    &a + 1  /* address one past the last element of the array */
    
    编辑:由于大众的需求,我在下面添加了一些有关阵列转换的信息

    除了三个例外,在表达式中,数组类型为
    T
    的对象转换为指向数组第一个元素的指针类型为
    T
    的值。例外情况是,如果对象是
    sizeof
    &
    一元运算符的操作数,或者如果对象是初始化数组的字符串文字

    例如,本声明:

    printf("a:%d\t&a:%d\n", a, &a);
    
    实际上相当于:

    printf("a:%d\t&a:%d\n", &a[0], &a);
    
    另外请注意,
    d
    转换说明符只能用于打印有符号整数;要打印指针值,必须使用
    p
    说明符(参数必须是
    void*
    )。因此,要正确做事,请使用:

    printf("a:%p\t&a:%p\n", (void *) a, (void *) &a);
    
    分别为:

    printf("a:%p\t&a:%p\n", (void *) &a[0], (void *) &a);
    
  • a和&a有相同的值。如何
  • 它们的值相同,但类型不同。数组对象在元素之间(之前或之后)没有填充,因此