LinuxでのC言語プログラミングの基礎知識


1.ソースプログラムのコンパイル
Linuxの下で、C言語のソースプログラムをコンパイルするには、GNUのgccコンパイラを使用します.次は
gccコンパイラの使用方法を一例で説明する.
次の非常に簡単なソースプログラム(hello.c)があるとします.
  int main(int argc,char **argv)
  {
  printf("Hello Linuxn");
  }

このプログラムをコンパイルするには、コマンドラインの下で実行します.
  gcc -o hello hello.c
gccコンパイラはhelloの実行可能なファイルを生成します.実行./ハローはプログラムを見ることができます
結果が出力されました.コマンドラインのgccは私たちがgccで私たちのソースプログラムをコンパイルしていることを示しています.-oオプションは私たちの要求を表しています.
コンパイラが出力してくれた実行可能ファイルの名前はhelloでhelloです.cは私たちのソースプログラムファイルです.
gccコンパイラには多くの選択肢がありますが、一般的にはその中のいくつかを知っていれば十分です.-oオプションはすでに
わかりました.出力を要求する実行可能なファイル名を示します.-cオプションは、コンパイラにターゲットコードの出力のみを要求することを示します.
実行可能ファイルを出力する必要はありません.-gオプションは、コンパイラがコンパイル時に後でスレッドを提供することを要求していることを示します.
デバッグをシーケンスする情報
この3つのオプションを知っていれば、自分で書いた簡単なソースプログラムをコンパイルすることができます.
gccのヘルプドキュメントを表示するには、他のオプションの詳細な説明がたくさんあります.
  2.Makefileの作成
ソースコードは次のようなプログラムがあるとします.
 
 /* main.c */
  #include "mytool1.h"
  #include "mytool2.h"
  
  int main(int argc,char **argv)
  {
  mytool1_print("hello");
  mytool2_print("hello");
  }
  
  /* mytool1.h */
  #ifndef _MYTOOL_1_H
  #define _MYTOOL_1_H
  
  void mytool1_print(char *print_str);
  
  #endif
  
  /* mytool1.c */
  #include "mytool1.h"
  void mytool1_print(char *print_str)
  {
  printf("This is mytool1 print %sn",print_str);
  }
  
  /* mytool2.h */
  #ifndef _MYTOOL_2_H
  #define _MYTOOL_2_H
  
  void mytool2_print(char *print_str);
  
  #endif
  
  /* mytool2.c */
  #include "mytool2.h"
  void mytool2_print(char *print_str)
  {
  printf("This is mytool2 print %sn",print_str);
  }

もちろんこのプログラムは短いのでコンパイルできます
  gcc -c main.c
  gcc -c mytool1.c
  gcc -c mytool2.c
  gcc -o main main.o mytool1.o mytool2.o
これでmainプログラムも生成でき、時々面倒になります.でも考えてみれば
ある日私たちはその中の1つのファイル(例えばmytool 1.c)を修正しました.では、私たちは再び上のファイルを入力しますか?
コマンド?これは簡単に解決できると言えるかもしれませんが、SHELLのスクリプトを書いて、彼女に完成させてくれればいいのではないでしょうか.
はい、このプログラムにとって、役に立ちます.しかし、私たちがもっと複雑なことを考えていると、もし私たちが
のプログラムが何百ものソースプログラムがあるとき、コンパイラももう一度コンパイルしなければなりませんか?
そのため、賢いプログラマーたちは良いツールを考え出してこのことをしました.これがmakeです.我々はただ
以下のmakeを使えば、上の問題を解決することができます.makeを実行する前に、非常に重いものを書きます.
必要なファイルMakefile.上記のプログラムでは、Makefileのファイルは次のようになります.
これは上のプログラムのMakefileファイルです
  main:main.o mytool1.o mytool2.o
  gcc -o main main.o mytool1.o mytool2.o
  main.o:main.c mytool1.h mytool2.h
  gcc -c main.c
  mytool1.o:mytool1.c mytool1.h
  gcc -c mytool1.c
  mytool2.o:mytool2.c mytool2.h
  gcc -c mytool2.c
このMakefileファイルがありますが、ソースプログラムのどのファイルをいつ修正しましたか.
makeコマンドを実行すると、私たちのコンパイラは私たちが修正したファイルに関連するファイルをコンパイルするだけで、他のファイルは彼女をコンパイルします.
理にも立たない
次はMakefileがどのように書かれているかを学びます.
Makefileでも#の最初の行はすべてコメント行です.Makefileで最も重要なのは、ファイルの依存関係を記述することです.
の説明を参照してください.一般的なフォーマットは次のとおりです.
  target: components
  TAB rule
1行目は依存関係を表す.2行目はルールです.
例えば上のMakefileファイルの2行目
  main:main.o mytool1.o mytool2.o
私たちのターゲットmainを表す依存オブジェクトはmainです.o mytool1.o
mytool2.o依存するオブジェクトがターゲット修正後に修正されると、ルール行で指定するコマンドを実行する.すぐ
私たちの上のMakefileの3行目のようにgcc-o main mainを実行します.o mytool1.o
mytool2.o注意ルール1行のTABは、そこがTABキーであることを示す
Makefileには3つの非常に有用な変数があります.それぞれ$@,$^,$<の意味はそれぞれ:
$@--ターゲットファイル、$^--すべての依存ファイル、$<--最初の依存ファイル.
上記の3つの変数を使用すると、Makefileファイルを簡略化できます.
これは簡略化されたMakefileです
  main:main.o mytool1.o mytool2.o
  gcc -o $@ $^
  main.o:main.c mytool1.h mytool2.h
  gcc -c $<
  mytool1.o:mytool1.c mytool1.h
  gcc -c $<
  mytool2.o:mytool2.c mytool2.h
  gcc -c $< 
簡略化された後、私たちのMakefileは少し簡単ですが、人々は時々簡単にしたいと思っています.ここでは
Makefileのデフォルトルールを学習
  .c.o:
  gcc -c $<
この規則はすべてを表す.oファイルはすべて依存して対応する.cファイルの例えばmytool.o mytooに依存
l.cこれでMakefileは次のようになります.
もう一度簡略化したMakefileです
  main:main.o mytool1.o mytool2.o
  gcc -o $@ $^
  .c.o:
  gcc -c $<
さて、私たちのMakefileもあまり悪くありません.Makefileルールについてもっと知りたいなら、相を見ることができます.
該当する文書
  
3.ライブラリへのリンク
次のプログラムをコンパイルしてみます
  
/* temp.c */
  #include <math.h>
  
  int main(int argc,char **argv)
  {
  double value;
  printf("Value:%fn",value);
  }

このプログラムはかなり簡単ですが、gcc-o temp tempを使うと.cコンパイル時に以下に示すエラーが発生する
错误
  
参照
/tmp/cc33Kydu.o: In function `main':
  /tmp/cc33Kydu.o(.text+0xe): undefined reference to `log'
  collect2: ld returned 1 exit status
このエラーはコンパイラがlogの具体的な実現を見つけられないためである.正しいヘッダファイルが含まれていますが、
私たちがコンパイルするときか、それとも特定のライブラリに接続しますか.Linuxでは数学関数を使うために
ライブラリ接続を学ぶには-lmオプションを追加します.gcc -o temp temp.c-lmはこれにより正確にコンパイルできる.
前にprintf関数を使ったとき、どうしてライブラリに接続しなかったのかと聞かれるかもしれません.このように、いくつかのよく使われる
の関数の実現、gccコンパイラは自動的にいくつかの常用ライブラリに接続して、このように私達は自分で指定する必要はありません.
コンパイラでライブラリのパスを指定する場合があります.この場合、コンパイラの-Lオプションを使用します.
パスを指定します.たとえば、/home/hoyt/mylibの下にライブラリがあります.これにより、コンパイル時に追加されます.
-L/home/hoyt/mylib.いくつかの標準ライブラリでは、パスを指摘する必要はありません.デフォルトライブラリにある限り
の経路でいいです.システムのデフォルトライブラリのパス/lib/usr/lib/usr/local/libこの3つのパス
次のライブラリでは、パスを指定しなくてもいいです.
もう一つ質問があります.ある関数を使ったことがありますが、ライブラリの名前が分かりません.この時はどうしますか.
どうする?申し訳ありませんが、この問題に対して私も答えを知りません.私には馬鹿な方法しかありません.まず、標準ライブラリパスの下に行きます.
私が使っている関数に関連するライブラリがあるかどうかを探して、スレッド(thread)関数のライブラリファイル(l)を見つけました.
ibpthread.a). もちろん、見つからないなら、愚かな方法しかありません.例えばsinという関数があるライブラリを探しています.
nm-o/lib/*を使うしかない.so|grep sin>~/sinコマンド、そして~/sinファイルを見て、その中を探しました.
sinファイルの中で、私はこのような行libm-2.1を見つけます.2.so:00009 fa 0 Wsinこれでsinがlibm-2.1にあることがわかりました.2.soライブラリの中で、私は-lmオプションを使えばいいです(前のlibと後ろのバージョンマークを消して、mが残っているので-lmです).もしあなたがどのように探しているか知っていたら、早く教えてください.私はとても感謝しています.ありがとう!
  
4.プログラムのデバッグ
私たちが書いたプログラムは一度に成功するはずがありません.私たちのプログラムの中には、たくさんの私が現れます.
私たちが思わなかった間違いは、この時私たちのプログラムをデバッグします.
最も一般的なデバッグソフトウェアはgdbである.グラフィックインタフェースでプログラムをデバッグしたい場合は、xxgdを選択できます.
b.コンパイル時に-gオプションを追加することを忘れないでください.gdbの使用についてはgdbのヘルプファイルを見ることができる.役に立たないから
このソフトを使ったことがあるので、使い方も言えません.でもgdbは好きじゃないプログラムを追跡するのは面倒だ
私は一般的にプログラムの中で中間変数の値を出力してプログラムをデバッグします.もちろん自分の方法を選ぶことができます
他人のことを学ぶ必要はない.今はIDE環境がたくさんあって、中にはもう自分でデバッガを持っています.あなたは何を選ぶことができますか?
自分の好きなものを見つけてみてください.
  
5.ヘッダファイルとシステムのヘルプ
時には1つの関数の大まかな形式しか知らないので、正確な表現を覚えていないか、関数を覚えていないことがあります.
そのヘッダファイルで説明した.この時、私たちはシステムを助けることができます.
例えばfreadという関数の正確な形式を知りたいのですが、man freadシステムを実行すれば負けます.
関数の詳細な解釈を示している.この関数が存在するヘッダファイル説明しました.もし私たちがwriteを必要としたら
個の関数の説明は、man writeを実行するとき、出力の結果は私たちが必要としない.なぜなら
writeという関数の説明ですが、writeというコマンドの説明が出てきました.writeの関数を得るために
明日はman 2 write.2は私たちが使っているwriteを表します.この関数はシステム呼び出し関数で、もう一つは私たちです.
3で表す関数がCであるライブラリ関数が一般的である.