程序的编译和链接过程
生活随笔
收集整理的這篇文章主要介紹了
程序的编译和链接过程
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一.虛擬機、linux簡介
簡單介紹一下虛擬機還有就是各種操作系統(tǒng),比如centos,Ubuntu
操作系統(tǒng):linux(centos、Ubuntu、redhat),Android,Windows(xp、win8、win10)
進程,多個程序,分時技術(shù),并行技術(shù)
一次打開多個程序,我們在只有一個cpu,如何讓這些程序進行執(zhí)行呢,看起來好像是在同時進行的,實際上是一個程序執(zhí)行了一點點時間,然后保存執(zhí)行的一些信息,接下來回來再次執(zhí)行,這樣就達到了看上去是多個程序在同時執(zhí)行的效果
操作系統(tǒng)的作用:控制程序的執(zhí)行,管理系統(tǒng)的資源
二.程序的編譯鏈接過程
2.1首先看一下預(yù)處理的指令
關(guān)于上面的預(yù)處理指令,大家可以自己測試一下
(測試例子)(注意是兩行) ANSI 標準 C 定義的幾個宏如下,大家可以簡單的了解一下 __LINE__ 表示正在編譯的文件的行號 __FILE__ 表示正在編譯的文件的名字 __DATE__ 表示編譯時刻的日期字符串,例如: "25 Dec 2007" __TIME__ 表示編譯時刻的時間字符串,例如: "12:30:55" __STDC__ 判斷該文件是不是定義成標準 C 程序
2.2宏定義 編譯器在預(yù)處理的時候,就會把宏定義的數(shù)據(jù)替換成它的元身,這里我們必須了解什么是宏,宏的主要的用法 2.2.1 定義宏常量 #define PI 3.14159265358979323846264338327 比如我們經(jīng)常使用的一個變量,如果這個變量的數(shù)值改變了之后,我們不需要再文件里面一個一個找,而是只需要把宏改變就可以了 #define ERROR_TEST -1 比如我們在test文件中,一些代碼的地方需要使用return -1,或者是exit(-1) 然后有很多類型的錯誤返回,如果每次返回的是-1,-2,-3之類的,一會就把自己給繞暈了 2.2.2定義字符串常量 #define PATH "c/file/linux" 這個一般用在表示文件的路徑的情況下有很多 (大家下去看一下,如果是一行寫不下怎么辦呢,就是比如一行太長了怎么辦) 2.2.3 定義注釋 #define ZZ // 因為在程序編譯的時候,注釋是先于宏處理的 2.2.4 定義表達式(宏函數(shù)) #define MUL(x) x*x 純文本替換 測試用例 MUL(5);MUL(1+2); --- 加上括號MUL((x)*(x)) MUL(5*3)*MUL(5*3) --- 大括號???不要吝嗇括號 2.2.5 空格 #define MUL (x) ((x)*(x)) 比如上面的宏函數(shù),我們要是定義成下面的這個樣子又是什么樣的呢 2.2.6#undef 撤銷宏定義 比如 #define PI 3.14159265358979323846264338327 ... ... ... #undef PI此時PI不在有效了 2.2.7定義宏函數(shù)補充 比如下面的程序 #define PRINTF printf("測試");
這個時候我們可以編寫 一個if esle語句 if(0) PRINTF; else printf("haha\n");
宏函數(shù)比普通函數(shù)的一些特性在哪里 (1)普通的函數(shù)需要建立棧幀,開銷較大,宏函數(shù)在效率上面更勝一籌 (2)函數(shù)中的參數(shù)必須使用特定的類型,換句話說,宏函數(shù)對參數(shù)是不進行類型檢查的,宏函數(shù)是不類型限制的
宏函數(shù)的缺點 宏函數(shù)每次是進行的代碼的替換,有時候可能會增加代碼的長度,使維護起來非常的復(fù)雜 宏函數(shù)的參數(shù)不能是一個類型
2.3. 條件編譯 第一種形式: #ifdef 標識符 程序段 1 #else 程序段 2 #endif 它的功能是,如果標識符已被 #define 命令定義過則對程序段 1 進行編譯;否則對程序段 2 進行編譯。
第二種形式 #ifndef 標識符程序段 1 #else 程序段 2 #endif
第三種形式 #if 常量表達式 程序段 1 #else 程序段 2 #endif
2.4. 文件包含 文件包含是預(yù)處理的一個重要功能,它可用來把多個源文件連接成一個源文件進行編譯,結(jié)果將生成一個目標文件。C語言提供#include 命令來實現(xiàn)文件包含的操作,它實際是宏替換的延伸,有兩種格式: #include<filename> #include"filename" 2.5.#pragma 預(yù)處理 自己上網(wǎng)調(diào)研,寫博客,寫測試用例 #pragma once #pragma warning #pragma pack--這個是張晨亮學長給你們講過的,設(shè)置內(nèi)置內(nèi)存對齊數(shù)
2.6詳解程序編譯和鏈接過程 程序的編譯和鏈接的過程 我們在linux下使用gcc編譯器直接對程序進行編譯,比如使用gcc test.c,然后就會生成一個程序叫做test.out 但是上面的看似簡單的過程實際上是經(jīng)歷了四個階段 預(yù)處理,編譯,匯編,連接 每個過程都有自己要完成的任務(wù)
記住一些操作,ESc對應(yīng)的是iso,
2.6.1. 預(yù)處理 通過預(yù)處理生成一個.i的文件,使用的指令是 gcc -E test.c -o test.i (G) 預(yù)處理過程主要處理的是1. 以#開始的預(yù)處理指令(保留#pragma)2.刪除所有的注釋3.添加文件名和行號,具體的過程如下
推薦書目:《程序員的自我修養(yǎng)--鏈接、裝載與庫》 《C語言深度剖析》
二.程序的編譯鏈接過程
2.1首先看一下預(yù)處理的指令
關(guān)于上面的預(yù)處理指令,大家可以自己測試一下
(測試例子)(注意是兩行) ANSI 標準 C 定義的幾個宏如下,大家可以簡單的了解一下 __LINE__ 表示正在編譯的文件的行號 __FILE__ 表示正在編譯的文件的名字 __DATE__ 表示編譯時刻的日期字符串,例如: "25 Dec 2007" __TIME__ 表示編譯時刻的時間字符串,例如: "12:30:55" __STDC__ 判斷該文件是不是定義成標準 C 程序
2.2宏定義 編譯器在預(yù)處理的時候,就會把宏定義的數(shù)據(jù)替換成它的元身,這里我們必須了解什么是宏,宏的主要的用法 2.2.1 定義宏常量 #define PI 3.14159265358979323846264338327 比如我們經(jīng)常使用的一個變量,如果這個變量的數(shù)值改變了之后,我們不需要再文件里面一個一個找,而是只需要把宏改變就可以了 #define ERROR_TEST -1 比如我們在test文件中,一些代碼的地方需要使用return -1,或者是exit(-1) 然后有很多類型的錯誤返回,如果每次返回的是-1,-2,-3之類的,一會就把自己給繞暈了 2.2.2定義字符串常量 #define PATH "c/file/linux" 這個一般用在表示文件的路徑的情況下有很多 (大家下去看一下,如果是一行寫不下怎么辦呢,就是比如一行太長了怎么辦) 2.2.3 定義注釋 #define ZZ // 因為在程序編譯的時候,注釋是先于宏處理的 2.2.4 定義表達式(宏函數(shù)) #define MUL(x) x*x 純文本替換 測試用例 MUL(5);MUL(1+2); --- 加上括號MUL((x)*(x)) MUL(5*3)*MUL(5*3) --- 大括號???不要吝嗇括號 2.2.5 空格 #define MUL (x) ((x)*(x)) 比如上面的宏函數(shù),我們要是定義成下面的這個樣子又是什么樣的呢 2.2.6#undef 撤銷宏定義 比如 #define PI 3.14159265358979323846264338327 ... ... ... #undef PI此時PI不在有效了 2.2.7定義宏函數(shù)補充 比如下面的程序 #define PRINTF printf("測試");
這個時候我們可以編寫 一個if esle語句 if(0) PRINTF; else printf("haha\n");
宏函數(shù)比普通函數(shù)的一些特性在哪里 (1)普通的函數(shù)需要建立棧幀,開銷較大,宏函數(shù)在效率上面更勝一籌 (2)函數(shù)中的參數(shù)必須使用特定的類型,換句話說,宏函數(shù)對參數(shù)是不進行類型檢查的,宏函數(shù)是不類型限制的
宏函數(shù)的缺點 宏函數(shù)每次是進行的代碼的替換,有時候可能會增加代碼的長度,使維護起來非常的復(fù)雜 宏函數(shù)的參數(shù)不能是一個類型
2.3. 條件編譯 第一種形式: #ifdef 標識符 程序段 1 #else 程序段 2 #endif 它的功能是,如果標識符已被 #define 命令定義過則對程序段 1 進行編譯;否則對程序段 2 進行編譯。
第二種形式 #ifndef 標識符程序段 1 #else 程序段 2 #endif
第三種形式 #if 常量表達式 程序段 1 #else 程序段 2 #endif
2.4. 文件包含 文件包含是預(yù)處理的一個重要功能,它可用來把多個源文件連接成一個源文件進行編譯,結(jié)果將生成一個目標文件。C語言提供#include 命令來實現(xiàn)文件包含的操作,它實際是宏替換的延伸,有兩種格式: #include<filename> #include"filename" 2.5.#pragma 預(yù)處理 自己上網(wǎng)調(diào)研,寫博客,寫測試用例 #pragma once #pragma warning #pragma pack--這個是張晨亮學長給你們講過的,設(shè)置內(nèi)置內(nèi)存對齊數(shù)
2.6詳解程序編譯和鏈接過程 程序的編譯和鏈接的過程 我們在linux下使用gcc編譯器直接對程序進行編譯,比如使用gcc test.c,然后就會生成一個程序叫做test.out 但是上面的看似簡單的過程實際上是經(jīng)歷了四個階段 預(yù)處理,編譯,匯編,連接 每個過程都有自己要完成的任務(wù)
記住一些操作,ESc對應(yīng)的是iso,
2.6.1. 預(yù)處理 通過預(yù)處理生成一個.i的文件,使用的指令是 gcc -E test.c -o test.i (G) 預(yù)處理過程主要處理的是1. 以#開始的預(yù)處理指令(保留#pragma)2.刪除所有的注釋3.添加文件名和行號,具體的過程如下
- 將所有的#define刪除,展開所有的宏定義
- 處理所有的條件預(yù)編譯指令,比如#if,#ifdef....
- 處理所有的#include預(yù)編譯指令,將所有被包含的文件包含至本文件中來
- 刪除所有的注釋,//和/* */等
- 保留所有的#pragma預(yù)處理指令,因為下面還要用到它
推薦書目:《程序員的自我修養(yǎng)--鏈接、裝載與庫》 《C語言深度剖析》
總結(jié)
以上是生活随笔為你收集整理的程序的编译和链接过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《我是歌手》,如果退赛会对比赛造成什么影
- 下一篇: vim编辑文章后不能修改