c語言 --- 程序環境

程序環境分爲兩種:翻譯環境和執行環境。
下面就對這些情況做下總結。

一.翻譯環境

  • (1.)翻譯環境中源代碼被轉換爲可執行的機器指令。
  • (2)組成一個程序的每個源文件通過編譯過程分別轉換爲目標代碼(object code)。
  • (3)每一個目標文件由鏈接器(linker)捆綁在一起,形成一個單一而完整的可執行程序。
  • (4)鏈接器同時也會引入標準c函數庫中任何被該程序所用到的函數,而且它可以搜索程序員個人的程序庫,將其需要的函數也鏈接到程序中

1.翻譯環境分爲以下幾個部分

  • (1)預處理:去掉註釋,宏替換,條件編譯,文件包含
  • gcc - E hello.c - o hello.i
  • (2)編譯:檢查代碼的規範性,是否有語法錯誤,將代碼翻譯爲彙編語言
  • gcc - S hello.i - o hello,s
  • (3)彙編:將編譯階段生成的“.c”文件轉換爲目標文件,生成機器可執行代碼。
  • gcc - C hello.s - o hello.o
  • (4)鏈接:生成可執行文件或者是庫文件
  • gcc hello.o - o hello

二.運行環境

程序執行的過程:

(1)程序必須載入內存中,在有操作系統的環境中:一般這個由操作系統完成。在獨立的環境中,
程序的載入必須由手工安排,也可能是通過可執行代碼置入只讀內存來完成。
(2)程序的執行便開始,接着便調用main函數。
(3)開始執行程序代碼,這時候程序使用一個運行時堆棧(stack),存儲函數的局部變量和返回地址。
程序同時也可以使用靜態(stctic)內存,存儲在靜態內存中的變量在程序的整個執行過程中一直保留他們的值。
(4)終止程序,正常終止main函數,也有可能是意外終止。

三.預處理詳解

預定義符號

FILE //進行編譯的源文件
LINE //文件當前的行號
DATE //文件被編譯的日期
TIME //文件被編譯的時間
STDC //如果編譯器遵循ANSIC,其值爲1.否則未定義

四.define

1.define定義標識符

#define name stuff
#define reg register //爲register這個關鍵字,創建一個簡短的名字

建議在使用define的時候不要在後面加上;否則會導致很多的錯誤。
2.define定義宏
(1)宏的定義方式

#define name(parament-list) stuff 其中的parament-list是一個由逗號隔開的符號表,他們可能出現在stuff中。
注意:參數列表的左括號必須與name緊鄰,如果兩者之間有任何的空白存在,參數列表就會被解釋爲stuff的一部分。

3.#define定義符號和宏的時候,需要涉及以下幾個步驟

  • 1.在調用宏時,首先對參數進行檢查,看着是否包含任何由#define定義的符號,如果是,它們首先被替換。
  • 2.替換文本隨後被插入到程序中原來文本的位置。對於宏,參數名被他們的值替換。
  • 3.最後,再次對結果文件進行掃描,看看它是否包含任何由#define定義的符號,如果是,就重複上述過程

五.宏和函數

宏通常被應用於執行簡單的運算。

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

那爲什麼不要函數來進行定義?原因在於:

  • (1)用於執行調用函數和從函數返回的代碼可能比實際執行這個小型計算工作所需要的時間多,所以宏比函數在程序的規模和速度方面更勝一籌。
  • (2)更重要的是函數的參數必須聲明爲特定的類型。所以函數只能在類型合適的表達式上使用,反之,這個宏怎可以適用於整形,長整形,浮點型等可以用來 > 來比較的類型。宏是類型無關的。

當然和函數相比宏也有劣勢的地方:

    1. 每次使用宏的時候,一份宏定義的代碼將插入到程序中。除非宏比較短,否則可能大幅度增加程序的長度。
    1. 宏是沒法調試的。
    1. 宏由於類型無關,也就不夠嚴謹。
    1. 宏可能會帶來運算符優先級的問題,導致程容易出現錯。

宏有時候可以做函數做不到的事情。比如:宏的參數可以出現類型,但是函數做不到.

#define MALLOC(num, type)\    
		(type *)malloc(num * sizeof(type)) 
... 
//使用 MALLOC(10, int);//類型作爲參數
 
//預處理器替換之後: 
(int *)malloc(10 * sizeof(int));

六.條件編譯

在編譯程序的時候我們如果要講一條語句編譯或者是放棄是很方便的,因爲我們有條件編譯指令。
比如說:

調試性的代碼,刪除可惜,保留又礙事,所以我們可以選擇性的編譯

#include<stdio.h>
#define _DEBUG_
int main()
{
	int i = 0;
	int arr[10] = {0};
	for(int i = 0;i < 10;i++)
	{
		arr[i] = i;
		#ifdef _DEBUG_
		printf("%d\n",arr[i]);
		#endif
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章