#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926
#define EARTH_RADIUS 6371393
double deg_to_rad(double deg) {
return deg / 180 * PI;
}
double hav(double theta) {
double s = sin(theta / 2);
return s * s;
}
double get_distance(double lat0, double lng0, double lat1, double lng1) {
lat0 = deg_to_rad(lat0);
lng0 = deg_to_rad(lng0);
lat1 = deg_to_rad(lat1);
lng1 = deg_to_rad(lng1);
double dlng = fabs(lng0 - lng1);
double dlat = fabs(lat0 - lat1);
double h = hav(dlat) + cos(lat0) * cos(lat1) * hav(dlng);
double distance = 2 * EARTH_RADIUS * asin(sqrt(h));
return distance;
}
int main() {
printf("%lf\n", deg_to_rad(180));
int* mem = calloc(1, sizeof(int));
*mem = 0;
int* mem2 = calloc(1, sizeof(int));
*mem2 = 2;
double lat0 = 50.985408;
double lng0 = 11.044170;
double lat1 = 50.985524;
double lng1 = 11.044168;
//printf("deg0: %lf\n", deg0);
//printf("deg1: %lf\n", deg1);
printf("distance: %lf\n", get_distance(lat0, lng0, lat1, lng1));
///get_distance();
free(mem);
free(mem2);
return 0;
}
當使用gcc編譯器編譯含數學函數的C程序時,會出現undefined reference to `sin'等錯誤.這種錯誤一般是由於缺少庫造成的.
(base) xiao@xiao-Inspiron-7590:~/Desktop/SDK_2.4.1/test/test0$ gcc get_distance.c -o get_distance
/usr/bin/ld: /tmp/ccP8GXmr.o: in function `hav':
get_distance.c:(.text+0x47): undefined reference to `sin'
/usr/bin/ld: /tmp/ccP8GXmr.o: in function `get_distance':
get_distance.c:(.text+0x143): undefined reference to `cos'
/usr/bin/ld: get_distance.c:(.text+0x15a): undefined reference to `cos'
/usr/bin/ld: get_distance.c:(.text+0x19b): undefined reference to `sqrt'
/usr/bin/ld: get_distance.c:(.text+0x1a0): undefined reference to `asin'
collect2: error: ld returned 1 exit status
使用gcc編譯時使用下列命令即可解決問題:
gcc get_distance.c -lm -o get_distance
其實,通過這個小問題,我們可以學習更多的知識。
思考如下:
明明是包含了math.h頭文件的,怎么還顯示sin沒有定義呢?
原來,gcc的sin函數是定義在libm.so里面了。
用-l選項定義指定的路徑。不填寫的話默認是/lib和/usr/lib內。而數學庫不在默認路徑下。
在Ubuntu20.04, gcc 7.5.0 的情況下,
數學庫所在位置:
/usr/lib/x86_64-linux-gnu/libm.a
因為linux下所有的函數庫都是以lib開頭的。所以除去頭和尾,那么m就是代表libm.so
(m是庫名,libm.so是庫文件名)
在使用“ -l”參數時,通常的習慣是除去“lib”函數庫頭和后面的版本號,使用庫名和參數“-l”連接,形成“-lm”。於是,我們需要在gcc找不到庫時,可以使用“-l”直接給定庫名。
對於使用cmake進行編譯,需要添加命令:
target_link_libraries(get_distance m)