【问题标题】:Wrong format warning in this c program此 c 程序中的格式错误警告
【发布时间】:2016-01-25 06:44:55
【问题描述】:

我正在尝试编译这个程序而没有警告,

#include<stdio.h>
int main()
{
    int arr[] = {1,2,3};
    printf("value1 = %d value2 %d\n", *(&arr+1), *(arr+1));//here is the warning
    return 0;
}

但是我收到了编译时警告

warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]

我正在 64 位 ubuntu 机器 gcc 版本 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 编译器上编译我的程序。

【问题讨论】:

  • *(&amp;arr+1) --> arr的地址(作为指向3个ints数组的指针),偏移3个ints数组的大小,然后取消引用得到一个包含 3 个ints 的数组,然后衰减到指向int 的指针(它指向arr 的原始开头之后的第4 个int,或第2 个数组的第一个int ints 起始地址为arr)。

标签: c


【解决方案1】:

&amp;arr 获取数组的地址,它是一个数组指针(不要与指向第一个元素的指针混淆)。它的类型为int(*)[3]

然后你对这个数组指针进行指针运算。因为它指向一个由 3 个整数组成的数组,&amp;arr + 1 的意思是“加上一个整个数组的大小”,你最终会指向刚刚声明的数组,这没有任何意义。

然后用* 获取数组指针的内容。然后,您将再次获得阵列本身。当您在表达式中使用数组时,它会衰减为指向其第一个元素int* 的指针。与int 不兼容,因此出现错误。

我猜您可能尝试使用&amp;arr[0] + 1arr + 1,它们的含义相同。

【讨论】:

  • 是的,我正在尝试做同样的事情。我正在寻找的是对此警告的合适解释。 *(&arr[0]) 也给了我同样的警告。
  • 我把参数 2 误解为 *(arr+1) 并且警告是由于它。
【解决方案2】:

arr 的类型是 int (*)[3],而不是 int *,尽管在大多数情况下,数组名称会衰减为指向第一个元素的指针,即在您的第二种情况下为 &amp;arr[0],这正是您的value2 正常输出。

但是,当arr&amp; 运算符的参数时,它不会衰减。因此,&amp;arr+1 具有与&amp;arr[0]+3 相同的值。这是因为sizeof &amp;arr 等于sizeof (int (*)[3]),产生3。因此,当尝试输出value1 时,您实际上正在访问&amp;arr[3],其类型为int *。它是&amp;arr[3],而不是arr[3],因为当您取消引用具有int (*)[3] 类型的东西时,它会衰减为一个指针。

如您所见,该警告确实是在试图将您从潜在的错误中拯救出来。

另请参阅:Exception to array not decaying into a pointer?

【讨论】:

    【解决方案3】:

    一步一步:

    arr 是类型“int 数组 3”。

    int arr[] = {1,2,3};
    

    &amp;arr 是类型“指向 int 数组 3 的指针”。

    &amp;arr + 1 也是类型“指向 int 数组 3 的指针”。

    *(&amp;arr+1) 是类型“int 数组 3”。

    将数组传递给函数时,会发生转换。传递的是数组第一个元素的地址,而不是数组本身。在这种情况下,它的类型为 int *

    "%d" 需要匹配的 int,因此编译器会发出警告:

    格式“%d”需要“int”类型的参数,但参数 2 的类型为“int *”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 2015-01-27
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多