首页 文章

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

提问于
浏览
2

当我尝试编译此代码时:

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 回答

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

    当前的问题是你错过了所需的 #include <stdio.h> ,但是's not the only problem with your code. Some of these things are errors that you can probably get away with (compilers may not complain, and may generate code that does what you expect), but there'没有理由不做正确的事 .

    #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);
    }
    

    解释我所做的改变:

    任何调用 printf 的程序都需要

    • #include <stdio.h> . 更确切地说,需要声明 printf<stdio.h> 提供它 . (原则上你可以写自己的声明,但没有充分的理由这样做 . )

    • main 的正确定义是 int main(void) . void main() 可能会被某些编译器接受,但它会使用一本书来告诉您使用 void main() ,它的作者不太了解该语言,并且可能给您其他错误的信息 . 找一本更好的书 . (警告: void main() ,或者更可能 void main(void) 可能实际上是某些嵌入式系统的首选实现定义形式 . 但您可能没有使用这样的系统 . )

    • "%ld" 格式需要 long int 类型的参数 . 打印指针值的唯一正确格式是 "%p" . 由于 "%p" 需要 void* 类型的参数,因此您应该将指针值显式转换为 void* . 省略强制转换可能是"work",但 float*void* 是不同的类型,并且不保证具有相同的表示或以相同的方式传递给函数 .

  • 6

    您需要包含 <stdio.h> 以禁止第一个警告并使用强制转换为 void * 并使用 %p 来禁止第二个警告 .

    在C90中,使用 printf() 而不使用 <stdio.h> 会调用未定义的行为,因为隐式声明与实际声明不匹配,因为 printf() 是可变参数 . (相比之下,使用 fputs() 就可以了 . )在C99中,不允许使用隐式声明,但GCC允许您编译此类代码 .

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

    %p 格式说明符用于打印指针 . 从技术上讲,它必须与 char *void * 指针一起使用 . 在现代系统中,这不会影响结果;但是将其他指针类型传递给 %p 将在技术上调用未定义的行为(这是不好的) .

    代码中的 %ld 格式是错误的,即使它适用于大多数系统 . 首先,它需要一个 long 参数,这需要一个演员表(即使演员阵容只会在一些系统上产生影响) . 其次,即使添加了强制转换,也不能保证指针中的所有信息都保留(它可能会切断位或执行其他操作) . 实际上,64位Windows系统是唯一能够在其他任何地方投射到最佳位置的系统 .

    所以使用 %p 并强制转换为 void * .

  • 2

    如果在定义函数之前使用它们,C会隐式声明函数,从而导致错误" incompatible implicit declaration of built-in function ‘printf’" . 要解决此问题,请在文件顶部添加 #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;
    }
    

相关问题