代码块编译的my程序与comand中的gcc不同

代码块编译的my程序与comand中的gcc不同,c,C,我今天试图检查一个答案,我意识到如果我使用代码块(带有gcc),我必须处理与使用gcc的命令行(Ubuntu Linux)不同的错误 程序是这样的: #include<stdio.h> #include<math.h> int main(void){ double len,x,y =0; int n=123456; len=floor(log10(abs(n))) + 1; x = n / pow(10, len / 2);

我今天试图检查一个答案,我意识到如果我使用代码块(带有gcc),我必须处理与使用gcc的命令行(Ubuntu Linux)不同的错误

程序是这样的:

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

int main(void){
    double len,x,y =0;
    int n=123456;

    len=floor(log10(abs(n))) + 1;

    x = n / pow(10, len / 2);
    y = n - x * pow(10, len / 2);

    printf("First Half = %f",x);
    printf("\nSecond Half = %f",y);

    return 0;
}
程序编译成功

我的问题是:为什么会发生这种情况? 我在interent上做了一项研究,发现有些人说abs函数是在stdlib.h中声明的,而不是在math.h中声明的。但是如果我在命令行中编译(不包括stdlib.h),使用-lm就可以了。我很困惑。

简短的回答:试试看

gcc -Wall -Wextra -pedantic -o program -lm

使其在出现警告时失败,就像代码块所做的那样

详细回答:链接到库与包含头文件完全不同。在C语言中,由于历史原因,“允许”使用未声明的函数。在本例中,编译器假定一个函数返回
int
,并接受您给定的任何参数。对于
abs()
,这些假设成立。因此,稍后,链接器在使用
libm
链接时找到函数,一切正常

但也有一些问题:首先,如果不启用警告,您将错过简单的打字错误。其次,编译器无法检查您提供的参数->提前崩溃程序。如果函数返回的不是
int
,则可能会出现更多的问题


abs()
stdlib.h
中声明。要使用它,请包含此标题。并始终启用编译器警告(代码块显然会为您提供警告)。

查看代码块中的命令行,它对每个文件都有此功能。它在构建日志中显示了这一点。将其与您在代码块外部使用的命令行进行比较。@B.Nadolson请解释一下……在底部窗口中,有一系列选项卡,如“搜索结果”、“生成日志”、“生成消息”。。。。每个源文件在编译每个文件时都会显示gcc-Winline-W-feexceptions-g-lld-D_DEBUG myfile.c-o myfile.o之类的内容。。。标题不是库
abs()
是在
stdlib.h
中声明的,在GNU C库中,实际的代码恰好可以在
libm.so
中找到,最后再重复一次:)然后再补充一点建议:Linux和GNU并不都在世界上,您通常必须小心在哪里可以找到函数的声明和实现,例如,在Linux和FreeBSD上,
dlopen()
dlfcn.h
中声明,但是在FreeBSD的
libc
(自动链接)和Linux的
libdl
(需要显式的
-ldl
)中可以找到实现。我一直使用这个“-Wall-Wextra-Werror-Wstrict原型-Wconversion-std=c11-Og”编译(代码块和命令行)。你说abs是在stdlib.h中声明的,为什么我可以在命令行中使用-lm编译程序而不包括stdlib.h?这与你的问题相矛盾:“如果我使用命令行(在终端中)使用comand:
gcc program.c-o program-lm
成功编译的程序。”--我在这里没有看到任何警告标志。我在回答中解释了为什么这个代码是可以接受的。曾经有一段时间,C甚至没有原型,因此可以省略函数声明是合理的。可能我不清楚,代码块在不包含stdlib.h的情况下是不会编译的,但在命令行(不包含stdlib.h)中添加-lm会编译。如果您使用代码块,请尝试第一个代码并解释。可能您没有仔细阅读我的答案?或者仅仅是关于
-Werror
?这会将所有警告变成错误,因此编译将停止。再一次<代码>-lm与此无关,它用于链接库(在编译器完成其工作之后)。没有它,你会从链接器中得到一个“未解析的符号”错误。先生,你在使用GCC吗?这可能是因为我使用Linux而你可能不使用?你根本帮不了我。如果我不在命令行中包含-lm,它将不会编译有或没有stdlib.h的程序。希望我把自己说清楚。“gcc program.c-o program/tmp/ccxOJHWB.o:In function
main”:program.c:(.text+0x2c):未定义对
log10'程序的引用。c:(.text+0x31):未定义对
floor'程序的引用。c:(.text+0x85):未定义对` pow'程序的引用。c:(.text+0xd2):错误:ld返回1退出状态”
   gcc program.c -o program -lm
gcc -Wall -Wextra -pedantic -o program -lm
gcc -Wall -Wextra -Werror -pedantic -o program -lm