“啪”和“地板”的含义不明

我试图用 C 语言做一个简单的斐波那契计算器,但是当编译 gcc时,我发现我错过了 pow 和 floor 函数。怎么了?

密码:

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


int fibo(int n);


int main() {
printf("Fib(4) = %d", fibo(4));
return 0;
}


int fibo(int n) {
double phi = 1.61803399;


return (int)(floor((float)(pow(phi, n) / sqrt(5)) + .5f));
}

产出:

gab@testvm:~/work/c/fibo$ gcc fib.c -o fibo
/tmp/ccNSjm4q.o: In function `fibo':
fib.c:(.text+0x4a): undefined reference to `pow'
fib.c:(.text+0x68): undefined reference to `floor'
collect2: ld returned 1 exit status
231017 次浏览

您需要使用链接标志 -lm进行编译,如下所示:

gcc fib.c -lm -o fibo

这将告诉 gcc 将您的代码链接到数学库。只要确保把标志 之后的对象,你想链接。

添加 lm 到您的链接选项中,因为 pow ()和 floor ()是数学库的一部分:

gcc fib.c -o fibo -lm

为了找到在 Eclipse-IDE 中添加-lm 的位置,实在是太可怕了,所以我花了一些时间。

如果其他人也使用 Edlipse,以下是添加命令的方法:

项目-> 属性-> C/C + + Build-> 设置-> GCC C Linker-> Miscelanous-> Linker 标志: 在这个字段中添加命令-lm

关于 Fuzzy 提供的答案:

实际上我不得不做一些稍微不同的事情。

Project-> Properties-> C/C + + Build-> Settings-> GCC C Linker-> Library

点击绿色的小图标,输入 m,然后点击 OK。这个窗口中的所有东西都自动地-l 应用于它,因为它是一个库。

为了以后阅读本文的人的利益,您需要链接到它,正如 Fred 所说:

gcc fib.c -lm -o fibo

找到需要链接的库的一个好方法是检查手册页(如果存在)。例如,man powman floor都会告诉你:

-lm连接。

关于 C 语言编程中数学库链接的说明—— 在 C 中连接

以上所有答案都是不完整的,这里的问题在于链接器 ld而不是编译器 collect2: ld returned 1 exit status。当你编译你的 fib.c对象:

$ gcc -c fib.c
$ nm fib.o
0000000000000028 T fibo
U floor
U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
U pow
U printf

其中 nm列出目标文件中的符号。您可以看到,这是编译没有错误,但 powfloorprintf函数有未定义的引用,现在如果我将尝试链接到可执行文件:

$ gcc fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status

我得到类似的输出你得到。为了解决这个问题,我需要告诉链接器在哪里查找对 powfloor的引用,为此,我将使用链接器 -l标志和来自 libm.so库的 m

$ gcc fib.o -lm
$ nm a.out
0000000000201010 B __bss_start
0000000000201010 b completed.7697
w __cxa_finalize@@GLIBC_2.2.5
0000000000201000 D __data_start
0000000000201000 W data_start
0000000000000620 t deregister_tm_clones
00000000000006b0 t __do_global_dtors_aux
0000000000200da0 t
__do_global_dtors_aux_fini_array_entry
0000000000201008 D __dso_handle
0000000000200da8 d _DYNAMIC
0000000000201010 D _edata
0000000000201018 B _end
0000000000000722 T fibo
0000000000000804 T _fini
U floor@@GLIBC_2.2.5
00000000000006f0 t frame_dummy
0000000000200d98 t __frame_dummy_init_array_entry
00000000000009a4 r __FRAME_END__
0000000000200fa8 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
000000000000083c r __GNU_EH_FRAME_HDR
0000000000000588 T _init
0000000000200da0 t __init_array_end
0000000000200d98 t __init_array_start
0000000000000810 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000000800 T __libc_csu_fini
0000000000000790 T __libc_csu_init
U __libc_start_main@@GLIBC_2.2.5
00000000000006fa T main
U pow@@GLIBC_2.2.5
U printf@@GLIBC_2.2.5
0000000000000660 t register_tm_clones
00000000000005f0 T _start
0000000000201010 D __TMC_END__

现在可以看到,函数 powfloor都链接到 GLIBC_2.2.5

参数顺序也很重要,除非您的系统默认配置为使用共享库,否则我的系统不会,所以当我发出:

$ gcc -lm fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status

在目标文件之前注意 -lm标志。因此,总而言之,要确保在所有其他标志和参数之后添加 -lm标志。