Next Previous Contents

5. 程式

在 Linux 上寫程式更是舒服:有許多好用得工具可以讓寫程式更加快速更加簡單。 例如:寫程式無非是單調沈悶的工作:編輯--存檔--離開--編譯--重新編輯 一直反覆的執行同樣的動作。 但是﹐如果使用像 emacs 或是 jed 等工具﹐上述那些動作﹐將統一整合在編輯器裡﹐一次完成。

5.1 Fortran

大體上﹐沒有多大的差別﹐但是請注意﹐這個免費的編譯器可不是百分之百的和 VMS 相容的。 可能會有些奇怪的結果發生。(實際上﹐VMS 的 Fortran 編譯器並不是一個可以標準延伸的(non-standard))。 詳細情形請看 /usr/doc/g77/DOC or /usr/doc/f2c/f2c.ps

您的系統管理員已經安裝了一個叫做 g77 的 compiler (不錯但是, 在 0.5.21 版, 還是沒有完全和 DEC 的 Fortran 百分百地相容) ﹐或是一個把 Fortran 轉成 C 語言的轉換器﹐叫做 f2c。 加上她的一個前端(front-ends)裝置﹐模擬就像是一個 Fortran 編譯器。 依我的經驗﹐yaf77 套件提供最好的解決方案。

欲使用 g77 來 compile 您的 Fortran 程式, 先用任意編輯記編輯程式碼﹐以副檔名 .f 存檔﹐ 然後執行如下:

$ g77 myprog.f

她會自動幫您產稱 a.out 的執行檔。(您不需要作任何 link 的動作) 如果想要產生不同的執行檔檔名﹐可以下參數:

$ g77 -O2 -o myprog myprog.f

請注意最佳化!要求您的系統管理員細讀編譯器的說明文件﹐並且告知您是否還有任何的存在問題。

編譯中間碼(subroutine):

$ g77 -c mysub.f

這會產生 mysub.o 這個檔案。 然後您需要作連結(link)的動作。

$ g77 -o myprog myprog.f mysub.o

如果您想作成函數庫(library)﹐您可以這樣作:

$ cd subroutines/
$ cat *f >mylib.f ; g77 -c mylib.f

這會產生出 mylib.o ﹐您可以使用她來連結您的程式。

最後﹐如果要 link 其他的函數庫(library)﹐我們假設 libdummy.so:

$ g77 -o myprog myprog.f -ldummy

如果您使用 f2c, 您只能使用 f77 或是 fort77 ﹐而不能使用 g77

另一個有用的工具是 make, 詳述如下:

5.2 如何使用 make

make 可以用來編輯很多分散於個檔案的原始碼。在 VMS 上我們稱為 MMSMMK, 但是她們和 Linux 有不同的語法。

假設您有一些原始程式﹐需要作些例行程序。程式分別為 file_1.f, file_2.f, file_3.f, 主程式為 myprog.f。 如果您是手動編譯您的程式﹐每當您修改您的程式碼後﹐ 您必須知道哪個檔案和哪個檔案有關連﹐哪個檔案必須先編譯﹐等等。

與其發瘋﹐不如您可以寫個 `makefile'。 這是一個文字檔﹐裡面記錄著您程式碼與程式碼之間的關連性。 當其中一個檔案被修改後﹐只有與這個被修改的檔案有相關的檔案需要被重新編譯。

例如﹐您寫了一個 makefile 如下:



# 這是一個 makefile
# 使用 <TAB> 鍵﹐當您見到 <TAB> 標籤時!
# 這非常的重要﹐請不要使用空白鍵代替。

myprog: myprog.o file_1.o file_2.o file_3.o
<TAB>g77 -o myprog myprog.o file_1.o file_2.o file_3.o
# myprog depends on four object files

myprog.o: myprog.f
<TAB>g77 -c myprog.f
# myprog.o depends on its source file

file_1.o: file_1.f
<TAB>g77 -c file_1.f
# file_1.o depends on its source file

file_2.o: file_2.f file_1.o
<TAB>g77 -c file_2.f file_1.o
# file_2.o depends on its source file and an object file

file_3.o: file_3.f file_2.o
<TAB>g77 -c file_3.f file_2.o
# file_3.o depends on its source file and an object file

# end of makefile.

儲存這個檔案﹐命名為 Makefile 且在命令列輸入 make 來編譯您的程式; 或是您也可以將她存成 myprog.mak 然後使用 make -f myprog.mak 來編譯. 接下來的後續動作, RMP.(還記得什麼是 RMP 吧!)

5.3 Shell Scripts

Shell scripts 就像 VMS 上的 command files。, 這可以建構出非常有用的功能。

要寫一個 script, 您所要作的就只是寫一個包含一些指令的文字檔﹐然後存檔﹐改變成可執行的模式 (使用 chmod +x <scriptfile>)。 只要輸入該 Script 的名字就可以執行了。

寫一個 Script 是一個非常重大的工程﹐這需要一本書。這裡我就不再多做說明了。

我只給您一個或多或少的綜合的(希望)有用的例子﹐您或許可以從這個例子中得到一些基本的規則。

EXAMPLE: sample.sh


#!/bin/sh
# sample.sh
# I am a comment
# 不要修改第一行﹐她必須以這種形式存在在第一行!!!
echo "This system is: `uname -a`" # use the output of the command
echo "My name is $0" # built-in variables
echo "You gave me the following $# parameters: "$*
echo "First parameter is: "$1
echo -n "What's your name? " ; read your_name
echo notice the difference: "hi $your_name" # quoting with "
echo notice the difference: 'hi $your_name' # quoting with '
DIRS=0 ; FILES=0
for file in `ls .` ; do
  if [ -d ${file} ] ; then # if file is a directory
    DIRS=`expr $DIRS + 1`  # this means DIRS = DIRS + 1
  elif [ -f ${file} ] ; then
    FILES=`expr $FILES + 1`
  fi
  case ${file} in
    *.gif|*jpg) echo "${file}: graphic file" ;;
    *.txt|*.tex) echo "${file}: text file" ;;
    *.c|*.f|*.for) echo "${file}: source file" ;;
    *) echo "${file}: generic file" ;;
  esac
done
echo "there are ${DIRS} directories and ${FILES} files"
ls | grep "ZxY--!!!WKW"
if [ $? != 0 ] ; then # exit code of last command
  echo "ZxY--!!!WKW not found"
fi
echo "enough... type 'man bash' if you want more info."

5.4 C 語言

Linux 是一個寫 C語言的好地方。就假設您會C語言吧!這裡也幾個指導方針。 編譯您的程式hello.c ﹐您會使用到 gcc compiler, 這已是 Linux 的一部份了。 而且和 g77 有相同的使用方法:

$ gcc -O2 -o hello hello.c

連結(link)函數庫(library)﹐加入參數 -l<libname>。 例如﹐要 link 數學函數庫和最佳化﹐可以下如下指令:

$ gcc -O2 -o mathprog mathprog.c -lm

( -l<libname> 參數強迫 gcc 連結(link)函數庫(library) /usr/lib/lib<libname>.a; 所以 -lm 就連結了 /usr/lib/libm.a).

如果您的程式是由許多檔案組成的﹐您可能也需要使用前面所提到的 make 這個工具。 在 makefile 使用 gcc 和 C語言的原始碼檔案就可以了。

您也可以獲得有關 C 語言的函數的說明。這些說明文件都已經被編成 man pages﹐第三節(section 3) 了。 例如:

$ man 3 printf

同時﹐有許許多多的函數庫可供使用。其中您第一想要使用的是 ncurses, 這可以用來處理文字模式下的特效。或是 svgalib, 這可以用來處理圖形模式。


Next Previous Contents