本週是學習C語言的第二週,遇到不少問題。真是應了一句古話:說來容易,做起來難。很多平時覺得挺簡單的技術,真正實現起來卻是問題不斷。遇到問題然後解決問題,也就是所謂的成長的過程吧。現將本週遇到的問題,總結如下:
1. 數學函數庫的編譯問題
當程序中使用了三角函數和一些常用數學函數時,需要做到如下兩點:
1,.包含頭文件:#include <math.h> ;
2. 編譯時需要加上鍊接選項: -lm 。
2. 變量重定義引起的編譯問題
當同一個頭文件被多個文件包含時,如果頭文件中定義了變量並且初始化了該變量,而變量卻沒有用static或者extern存儲類說明符聲明時,編譯會出現“multiple definition of xxx”的出錯信息。
解決辦法:如果是全局變量,則在頭文件中用extern聲明該變量,並且只在包含該頭文件中的某個文件中定義一次該變量。如果是局部變量,則用static定義並初始化該變量。(如果非必要,最好不要在頭文件中定義變量)。
3. 編譯時找不到頭文件 “No suchfile or directory”
編譯時因爲找不到頭文件的正確路徑而引起的問題: “Nosuch file or directory”
解決辦法:設置編譯選項CFLAGS += -I 頭文件所在目錄路徑
4. 鏈接時找不到庫文件問題“undefined reference to”
編譯鏈接時因爲找不到庫文件的正確路徑而引起的問題: “undefined reference to”
解決辦法:設置鏈接選項LDFLAGS += -l庫名 –L庫文件所在目錄路徑(其中庫名爲去掉前面lib後的文件名,比如庫文件libm.so, 對應的寫法爲:-lm)
5. 鏈接動態庫文件,運行時出現錯誤“error while loading shared libraries:xxx.so
如果程序編譯時鏈接的是動態庫,則程序運行時,需要有動態庫文件存在,如果動態庫文件不在默認路徑下或者根本就不存在,程序運行時會出現錯誤“error while loading shared libraries: xxx.so”。
如果動態庫存在,只是路徑不對時,有以下幾種解決方法:
1. 修改/etc/ld.so.conf,將動態庫的路徑加入文件中,然後執行命令:ldconfig,如:# echo"/usr/local/lib" >> /etc/ld.so.conf
# ldconfig
2.設置環境變量LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/mysql/lib:$LD_LIBRARY_PATH
3.如果程序需要的庫文件比系統目前存在的村文件版本低,可以做一個鏈接
比如:
error while loading sharedlibraries: libncurses.so.4: cannot open shared
object file: No such file or directory
/usr/lib/libncurses.a /usr/lib/libncurses.so.5
/usr/lib/libncurses.so /usr/lib/libncurses.so.5.3
6. 編譯時設置爲靜態鏈接
當庫文件目錄下,相同名字的靜態庫(.a)和動態庫(.so)同時存在時,編譯鏈接選項如果是“ –l庫名 -L庫路徑”, 默認識別爲動態庫。
如果想要設置爲靜態庫,則用編譯選項“-static –l庫名 -L庫路徑”。 如果是靜態鏈接,編譯時必須注意LDFLAGS的使用順序,$^ 必須寫在$(LDFLAGS)之前,否則出錯。
7. shell腳本里設置外部環境變量失效問題
在腳本里用export 設置外部環境變量,如果用 ./腳本名 執行,退出腳本後,環境變量不會生效。
原因:./腳本名 // 創建一個新的shell,在新shell中執行腳本,腳本必須具有可執行x權限
解決辦法:用 source 腳本名 //在當前shell中執行腳本,腳本可以不具有可執行x權限
或者 . 腳本名 //在當前shell中執行腳本,腳本可以不具有可執行x權限
執行腳本即可。
8. SSH中空格顯示爲下劃線
SSH中,用vi編輯C程序源文件,空格顯示爲下劃線。
原因:SSH中的環境變量TERM默認設置爲vt100。
解決辦法:將TERM設置爲xterm。設置方法如下:
Profile Setting- > Connection -> Terminal -> xterm。
設置好後用env 查看雖有環境變量,或者用 echo $TERM 查看當前的TERM設置值。
9.顯示中文亂碼
如果程序中有中文註釋顯示亂碼,
解決辦法:
exportLC_ALL=zh_CN.GB2312
exportLANG=zh_CN.GB2312
10. 動態鏈接出錯”undefined reference to `__stack_chk_fail_local'”
原因: gcc版本高了,gcc 4.0以前的版本是用ld –share來生成共享庫的,但是到了gcc 4.0以後的版本,這個命令就改成了gcc -share。 在終端裏輸入gcc -v查看,我的版本是gcc version4.4.3。
解決方法:
方法一:修改makefile ,將LD = ld 修改爲 LD=gcc。
方法二:在編譯選項CFLAGS中加入-fno-stack-protector。如:
CFLAGS = -Wall-O -g -fPIC -fno-stack-protector -I ../include
11.顯示:warning: suggestparentheses around && within ||
警告原因:假如使用了這樣的語句:
if(( *p >= 'a' ) && ( *p <='z' ) || ( *p >= 'A' ) && ( *p <= 'Z' ) || ( *p >= '0' )&& ( *p <= '9' ))
解決方法:你最好這樣if(((*p >= 'a' ) && ( *p <= 'z' )) || (( *p >= 'A' ) && (*p <= 'Z' ))|| (( *p >= '0' ) && ( *p <= '9' )))
即:|| 的前後表達式都用括號括起來,更加明確層次關係。