C言語-プログラムのコンパイルとリンク

翻訳環境と実行環境

C言語の実装には、次の2つの環境が必要です。

  • ソースコードを実行可能なマシン命令に変換する変換環境
  • 実際にコードを実行するために使用される実行環境

コンパイルとリンクとは何ですか?

翻訳環境では、ソースファイルはコンパイラを介してオブジェクトファイルに変換され、複数のオブジェクトファイルはリンカを介して実行可能プログラムに形成されます。(翻訳プロセスは図に示されています)

 細分化されたコンパイルプロセスもいくつかの段階に分かれています。

  • 1.前処理gcc-Etest.c -o test.i
  • 2. gcc-Stest.cをコンパイルします
  • 3. gcc-ctest.cをアセンブルします

まず、実行環境が何をするのかを見てから、上記のプロセスを詳しく見ていきましょう。

  • 1.プログラムのメモリへのロードは通常、オペレーティングシステムによって行われ、独立した環境で操作する必要があります。
  • 2.実行が開始され、main関数が呼び出されます。
  • 3.プログラムコードの実行を開始します。この時点で、プログラムはランタイムスタック(スタック)を使用して、関数のローカル変数とリターンアドレスを格納します。プログラムは静的メモリを使用することもできます。静的メモリに格納されている変数は、プログラムの実行中、その値を保持します。
  • 4.プログラムを終了します。main関数を正常に終了します。予期せず終了する場合もあります。

前処理記号

__FILE__//コンパイルされるソースファイル__LINE__//ファイル
の現在の行番号__DATE__//ファイルがコンパイルされ
た日付
__TIME__//ファイルがコンパイルされた時刻__STDC
__//コンパイラがANSICに従っている場合、その値は1、それ以外は未定義

#定義

識別子を定義する

#define MAX 1000
#define regregister//キーワードレジスタの短い名前を作成します
#definedo_foreverfor(;;)//実装をより鮮明な表記に置き換えます
#define CASE break; case//in書き込み時に自動的にbreakを書き込みますケースステートメント

マクロを定義する

パラメータをテキストに置き換えて、この実装はマクロの定義と呼ばれます。

#define SQUARE(x)x * x

ただし、このマクロには問題があります。

質問1

int a = 5;
printf( "%d \ n"、SQUARE(a + 1));

達成したい値は36ですが、実際の出力は11です。なぜですか?

 printf( "%d \ n"、a + 1 * a + 1);

実際の置換は5+1 * 5 + 1、つまり11です。

上記の問題を解決したい場合は、括弧を入れてください。

#define SQUARE(x)(x)*(x)

しかし、興味深い新しい質問が以下に発生します

質問2

#define DOUBLE(x)(x)+(x)

int a = 5;
printf( "%d \ n"、10 * DOUBLE(a));

100を印刷することを期待していましたが、実際には55を出力します。

printf( "%d \ n"、10 *(5)+(5));

これを解決する方法は?別の括弧を追加します(どちらの質問も基本的に優先順位の問題を解決するためのものです)

#define DOUBLE(x)((x)+(x))

文字列をマクロパラメータとして使用する場合、文字列を文字列に入れることができます。

 

##の役割

##は、その周りのシンボルを1つのシンボルに組み合わせることができます。

#define ADD_TO_SUM(num、value)
sum ## num + = value;
...
ADD_TO_SUM(5、10); //関数は次のとおりです:sum5に10を追加します。

#define MAX(a、b)((a)>(b)?(a):(b))
...
x = 5;
y = 8;
z = MAX(x ++、y ++);
printf( "x = %dy =%dz =%d \ n "、x、y、z); //出力結果はどうなりますか?

 実際には、z =((x ++)>(y ++)?(x ++):(y ++));

x ++を1回、y ++を2回、最初の++の後の値をzに割り当てます。

マクロと関数

マクロは、単純な操作を実行するためによく使用されます。サイズの比較など

#define MAX(a、b)((a)>(b)?(a):(b))

では、関数を使ってみませんか?

  • 1.関数を呼び出して関数から戻るためのコードは、この小さな計算作業を実際に行うよりも時間がかかる場合があります。したがって、マクロはプログラムのサイズと速度の点で関数よりも優れています。
  • 2.さらに重要なことに、関数のパラメーターは特定の型として宣言する必要があります。したがって、関数は適切なタイプの式でのみ使用できます。逆に、このマクロは、型を比較す​​るために>に使用できる整数、長整数、浮動小数点型などにどのように適用できますか。マクロはタイプに依存しません

マクロに欠点はありますか?

  • 1.マクロを使用するたびに、マクロ定義コードのコピーがプログラムに挿入されます。マクロが比較的短い場合を除いて、プログラムの長さが大幅に長くなる可能性があります。
  • 2.マクロはデバッグできません。
  • 3.マクロはタイプに依存しないため、厳密ではありません。
  • 4.マクロは、演算子の優先順位に問題を引き起こし、プロシージャにエラーが発生しやすくなる可能性があります。

2つを1つのグラフにまとめました。

 

#undef

 このディレクティブは、マクロ定義を削除するために使用されます

#undef NAME
//既存の名前を再定義する必要がある場合は、最初に古い名前を削除する必要があります。

コンパイルを開始

多くのCコンパイラは、コマンドラインでシンボルを定義する機能を提供します。コンパイルプロセスを開始するために使用されます。たとえば、この機能は、同じソースファイルに基づいて異なるバージョンのプログラムをコンパイルする場合に役立ちます。

#include <stdio.h>
int main()
{
  int array [ARRAY_SIZE];
  int i = 0;
  for(i = 0; i< ARRAY_SIZE; i ++)
  {
    array[i] = i;
  }
  for(i = 0; i< ARRAY_SIZE; i ++)
  {
    printf("%d " ,array[i]);
  }
  printf("\n" );
  return 0;
}

gcc -D ARRAY_SIZE = 10 programe.c

ファイルに含まれています

  • ローカルファイル

#include"ファイル名"

  • ライブラリファイルには

#include <filename.h>

おすすめ

転載: blog.csdn.net/qq_59392324/article/details/122143879