a.c
1 #include <stdio.h> 2 #include <math.h> 3 int main() 4 { 5 float a; 6 void print_logarithm(double); 7 printf("enter a num:"); 8 scanf("%f",&a); 9 print_logarithm(a); 10 return 0; 11 } 12 void print_logarithm(double x) 13 { 14 if(x<=0.0) 15 { 16 printf("Positive numbers only,please.\n"); 17 return; 18 } 19 printf("The log of x is %f",log(x)); 20 }
Ubuntu gcc編譯
直接命令gcc -Wall a.c
1 tgs@tgs-VirtualBox:~$ gcc -Wall a.c 2 /tmp/ccmKjOLq.o:在函數‘print_logarithm’中: 3 a.c:(.text+0x97):對‘log’未定義的引用 4 collect2: error: ld returned 1 exit status
查了一下發現:主要是C/C++編譯為obj
文件的時候並不需要函數的具體實現,只要有函數的原型即可。但是在鏈接為可執行文件的時候就必須要具體的實現了。驗證如下:
1 tgs@tgs-VirtualBox:~$ gcc -Wall -c a.c 2 tgs@tgs-VirtualBox:~$ gcc -Wall -o a a.o 3 a.o:在函數‘print_logarithm’中: 4 a.c:(.text+0x97):對‘log’未定義的引用 5 collect2: error: ld returned 1 exit status 6 tgs@tgs-VirtualBox:~$
編譯時沒有問題,鏈接生成可執行文件時報錯。接下來加上-lm。 鏈接成功,如下:
1 tgs@tgs-VirtualBox:~$ gcc -Wall -o a a.o -lm 2 tgs@tgs-VirtualBox:~$
注意1:-lm要加在編譯文件后面。
這個主要的原因是gcc
編譯的時候,各個文件依賴順序的問題。在gcc
編譯的時候,如果文件a
依賴於文件b
,那么編譯的時候必須把a
放前面,b
放后面。
注意2:sqrt()函數也是<math.h>頭文件中的函數,但sqrt函數的使用沒有以上限制,即編譯時不加-lm也可以。