天天看點

C語言預處理1

程式的翻譯環境和執行環境

​在ANSI C的任何一種實作中,存在兩種不同的環境。

---第一種是翻譯環境,在這個環境中原代碼被轉換為可執行的機器指令。

---第二種是執行化境,它用于實際執行代碼。

編譯和連結:

C語言預處理1
C語言預處理1

一。翻譯環境:

Linux環境下:

gcc -E test.c >test.i 進行預編譯

1.#include

頭檔案的包含

2.注釋删除

使用空格開 替換注釋

3.#define 文本替換

gcc -S test.i >test.s進行編譯 - 把c語言代碼翻譯成彙編代碼

​文法分析,詞法分析,語義分析,符号彙總

gcc - c test.s >test.o 彙編 - 把彙編代碼轉換成了二進制指令​

形成符号表

連結:Add.o和test.o

1.合并段表

2.符号表的合并和重定位

二。運作環境

程式執行過程:

C語言預處理1

三。預編譯詳解

1.預定義符号

__ FILE__ 進行編譯的原檔案

__ LINE__ 檔案目前的行号

__ DATE__檔案被編譯的日期

__ TIME__ 檔案被編譯的時間

__STDC__如果編譯器遵循ANSI C ,其值為1,否則未定義

#include<stdio.h>

#define MAX 100

int main()
{
  printf("%s\n", __FILE__);
  printf("%d\n", __LINE__);
  printf("%s\n", __DATE__);
  printf("%s\n", __TIME__);
  return 0;
}      
C語言預處理1

示例:寫日志檔案

int main()
{
  //printf("%s\n", __FILE__);
  //printf("%d\n", __LINE__);
  //printf("%s\n", __DATE__);
  //printf("%s\n", __TIME__);

  int i = 0;
  int arr[10] = { 0 };
  FILE* pf = fopen("log.txt", "w");
  for (i = 0; i < 10; i++)
  {
    arr[i] = i;
    fprintf(pf, "file:%s line:%d time:%s data:%s i=%d\n",
      __FILE__, __LINE__, __TIME__, __DATE__,i);
  }
  fclose(pf);
  pf = NULL;
  for (i = 0; i < 10; i++)
  {
    printf("%d ", arr[i]);
  }
  return 0;
}      
C語言預處理1

2.#define 預定義辨別符

 #define MAX 100 常量

#define STR "hehehe"

#define reg register 簡易命名

#define do_forever for(; ; ) 死循環

#define 定義宏

C語言預處理1

5*5 = 25

#define SQUARE(X) X*X

int main()
{
  int ret = SQUARE(5);
  printf("%d\n", ret);
  return 0;
}      
C語言預處理1

宏不傳參,宏是進行完全替換

故:5+1*5+1 =  11

#define SQUARE(X) X*X

int main()
{
  int ret = SQUARE(5+1);
  printf("%d\n", ret);
  return 0;
}      
C語言預處理1

10*5+5 = 55

#define DOUBLE(X) X+X

int main()
{
  int a = 5;
  int ret = 10 * DOUBlE(a);
  return 0;
}      

#define替換規則

C語言預處理1

注意:

1.宏不可以出現遞歸

2.字元串常量二點内容并不被替換 如: “MAX= %d\n”

3.# 和 ##

1) #的作用是:把宏的參數轉換成對應字元串,插入宏中

提出問題:如何把宏的參數插入字元串?

#define PRINT(X) printf("the value of X is %d\n",X)

int main()
{
  int a = 10;
  int b = 20;
  //printf("the value of a is %d\n", a);
  PRINT(a);
  PRINT(b);
  return 0;
}
      

運作結果:都為X

C語言預處理1
#define PRINT(X) printf("the value of" #X "is %d\n",X)

int main()
{
  int a = 10;
  int b = 20;
  PRINT(a);
  //printf("the value of" "a" "is %d\n", a);

  PRINT(b);
  //printf("the value of" "b" "is %d\n", b);

  return 0;
}
      
C語言預處理1

2)##的作用 :可以把位于兩邊的符号合成一個符号,它允許宏定義從分離的文本片段建立辨別符

#define CAT(X,Y) X##Y

int main()
{
  int Class84 = 2019;

  printf("%d\n",CAT(Class,84));
    //printf("%d\n", Class##84);

  return 0;
}      
C語言預處理1