数组是指向第一个元素的指针,如果是的话......?

时间:2016-05-01 21:09:53

标签: c arrays

...那么为什么下面的代码给出地址和实际内容的相同值(肉丸)?如何理解肉丸的%d值,它是随机的吗?

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int main()
{
    int i;
    int meatballs[5]= {1,2,3,4,5};

    printf("\nmeatsballs %p %p %d \t \n",meatballs, &meatballs, 
          meatballs);

    return 0;

}

2 个答案:

答案 0 :(得分:3)

  1. meatballs是一个数组,类型为int[5]。但是,C不允许按值传递数组,因此数组衰减为函数调用的指针。这相当于指向数组&meatballs[0]的第一个元素的指针,它的类型为int*

  2. &meatballs是指向数组的指针,它的类型为int(*)[5]。由于它是一个指针,因此可以传递给函数。

  3. 如您所见,1和2都返回相同的地址,但它们有不同的类型:指向整数数组的指针与指向单个整数的指针。

    注意:类型void*int*不必具有相同的表示(1),以及{{1只有有效类型为%p (2),否则您将获得未定义行为 (3)。打印地址时始终将指针转换为void*

    void*
    1. 最后一种情况与第一种情况相同,但您使用了错误的类型说明符printf("%p %p", (void*)meatballs, (void*)&meatballs); 。与案例1一样,结果类型再次为%d,但它被解释为int*。这是明确的未定义的行为,输出是垃圾。
    2. 要打印整数数组元素,请使用以下任一方法:

      int

      前两个将在索引printf("%d %d %d", meatballs[i], *(meatballs + i), *meatballs); 打印数组元素,最后两个将打印第一个元素。我建议在大多数情况下使用i,因为它最清楚。

      参考C标准(草案):

      1. N1570,6.2.5第28段
          

        指向 void 的指针应具有与指向字符类型的指针相同的表示和对齐要求。 48) ......指向其他类型的指针需要没有相同的表示或对齐要求。

      2. N1570,7.21.6第8段
          

        p 参数应为指向 void 的指针。 ...

      3. N1570,7.21.6第9段
          

        ......如果有任何争论   不是相应转换规范的正确类型,行为是   未定义。

答案 1 :(得分:0)

您必须使用一元解除引用运算符*,以便实际值显示为%d期望整数。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int main()
{
    int i;
    int meatballs[5]= {1,2,3,4,5};

    printf("\nmeatsballs %p %p %d \t \n",meatballs, &meatballs, 
          *meatballs);

    return 0;

}

查看最后一个参数:*meatballs。此代码实际上将1打印为值,并且是数组中的第一个元素。所以你的猜测是正确的,这只是一个错误。