使用带浮点指针的printf会产生错误

时间:2014-02-05 20:52:58

标签: c pointers floating-point printf

当我尝试编译此代码时:

void main()
{
float x;
    x=6.5;
    printf("Value of x is %f, address of x %ld\n", x, &x);
}

它给了我这个错误:

pruebaso.c:在函数'main'中:

pruebaso.c:5:9:警告:内置函数'printf'的不兼容隐式声明[默认启用]

printf(“x的值为%f,地址为x%ld \ n”,x和& x);

^

pruebaso.c:5:9:警告:格式'%ld'需要类型为'long int'的参数,但参数3的类型为'float *'[-Wformat =]

我在另一个论坛中看到解决方案是首先对一个void指针进行强制转换: http://www.linuxquestions.org/questions/programming-9/beginning-c-programming-how-to-print-memory-locations-printf-conversion-number-927305/

但要做出这样的改变,

printf("Value of x is %f, address of x %ld\n", (double)x, (void *)&x);

现在给我一个警告:

pruebaso.c:在函数'main'中:

pruebaso.c:5:9:警告:内置函数'printf'的不兼容隐式声明[默认启用]

printf(“x的值为%f,地址为x%ld \ n”,(double)x,(void *)& x);

^

pruebaso.c:5:9:警告:格式'%ld'需要类型为'long int'的参数,但参数3的类型为'void *'[-Wformat =]

有人可以解释我如何在没有收到警告的情况下解决问题吗?

谢谢

3 个答案:

答案 0 :(得分:7)

您需要包含<stdio.h>以取消第一次警告,并使用强制转换为void *并使用%p来取消第二次警告。

在C90中,使用不带printf()的{​​{1}}会调用未定义的行为,因为隐式声明与实际声明不匹配,因为<stdio.h>是可变参数。 (通过比较,使用printf()会没问题。)在C99中,不允许隐式声明,但GCC允许你编译这样的代码。

fputs()

#include <stdio.h> int main(void) { float x = 6.5; printf("Value of x is %f, address of x %p\n", x, (void *) &x); } 格式说明符用于打印指针。从技术上讲,它必须与%pchar *指针一起使用。在现代系统中,这不会影响结果;但是将其他指针类型传递给void *在技术上会调用未定义的行为(这很糟糕)。

代码中的%p格式是错误的,即使它适用于大多数系统。首先,它需要一个%ld参数,这需要一个演员表(即使演员阵容只会在一些系统上产生影响)。其次,即使添加了强制转换,也不能保证指针中的所有信息都保留(它可能会切断位或执行其他操作)。在实践中,64位Windows系统是唯一一个转换为long比特的系统,并且其他地方的转换工作正常。

因此请使用long并转换为%p

答案 1 :(得分:6)

void main()
{
    float x;
    x=6.5;
    printf("Value of x is %f, address of x %ld\n", x, &x);
}

当前的问题是您错过了所需的#include <stdio.h>,但这不是您的代码唯一的问题。其中一些是您可能会忘记的错误(编译器可能不会抱怨,并且可能生成符合您期望的代码),但没有理由不这样做。

#include <stdio.h>
int main(void)
{
    float x;
    x = 6.5;
    printf("Value of x is %f, address of x %p\n", x, (void*)&x);
}

解释我所做的更改:

    任何调用#include <stdio.h>的程序都需要
  • printf。更准确地说,需要printf声明,<stdio.h>提供声明。 (原则上你可以写自己的声明,但没有充分的理由这样做。)
  • main的正确定义是int main(void)。某些编译器可能会接受void main(),但它主要用作检测坏书的方法。如果您使用的是一本告诉您使用void main()的书籍,那么其作者并不会非常了解该语言,并且可能会向您提供其他错误信息。找一本更好的书。 (警告:void main(),或者更可能void main(void)可能实际上是某些嵌入式系统的首选实现定义形式。但您可能没有使用这样的系统。)
  • "%ld"格式需要long int类型的参数。打印指针值的唯一正确格式是"%p"。由于"%p"需要类型为void*的参数,因此您应该将指针值显式转换为void*。省略演员表可能“有效”,但float*void*是不同的类型,并且不保证具有相同的表示或以相同的方式传递给函数。

答案 2 :(得分:2)

C隐式声明函数,如果你在定义它之前使用它们,这会导致错误&#34;内置函数'printf'&#34;的不兼容的隐式声明。 要解决此问题,请在文件顶部添加#include <stdio.h>(这将复制到包含printf声明的头文件。

第二个问题是您应该使用%p来打印指针。

结果代码是

#include <stdio.h>
int main(void)
{
  float x;
  x=6.5;
  printf("Value of x is %f, address of x %p\n", x, (void *) &x);
  return 0;
}