泛化程式設計與預編譯

2021-10-05 09:10:03 字數 3801 閱讀 9584

為實現**的可移植性和可重用性,c語言引入預編譯指令。

預編譯指令以符號#開始,可以出現在源程式的任何位置,其作用範圍是從出現位置到檔案尾。

#define 指令用於巨集定義

指令格式:

#define 符號常量名 替換文字 (沒有分號)

符號常量名也稱巨集名,習慣用大寫字母表示。

替換文字可以是c語言允許的識別符號,關鍵字,數值,運算子,字串已經語句等

通過預編譯處理,( 編譯器對源程式進行編譯時,首先處理預編譯指令。)程式中使用的符號常量名都被替換文字所替換,該過程稱為巨集展開

結論:程式執行時,所有的符號常量名都被替換為替換文字

使用不帶引數的巨集定義時需注意: (假如pi是符號常量名)

①字串中與符號常量名相同的字串不進行替換

如:「pi」 不能替換,pipi也不能替換

②巨集定義只是簡單的字元替換,不進行語法檢查

③每條巨集定義必須單獨佔一行

④巨集不可以被定義多次,但巨集定義可以使用已經定義的巨集

⑤巨集定義只作字元替換,不分配記憶體

⑥#undef 指令可以取消巨集定義,此後,某個巨集將不存在

指令格式: #undef 符號常量名

**演示:

#include

#define pi 3.1415926

//pi是符號常量名,3.14 是替換文字

#define 乘 *

//乘 是符號常量名,* 是替換文字

#define 等於 =

//等於 是符號常量名,= 是替換文字

#define 實數 float

//實數 是符號常量名, float 是替換文字

#define s pi*2*2

//s 是符號常量名, p*4*4 是替換文字

intmain()

巨集定可以帶引數,這些引數相當於實際引數的佔位符

指令格式:

#define 巨集名(形參列表) 巨集體 (巨集名之後沒有空格)

**演示:

#include

#define pi 3.14

#define area(r) pi*r*r

intmain()

巨集定義編譯時進行處理,巨集展開不分配儲存空間,展開過程占用編譯時間,不占用程式執行時間。

函式在程式執行期間被呼叫,系統為其分配臨時記憶體,函式呼叫占用程式執行時間。

②巨集展開只是進行對應的字元替換。

函式呼叫時,先計算實參的值,再傳入實參。

③巨集定義不存在型別問題,巨集名無型別,其他引數也無型別。

④巨集展開過程會使源程式**增加,編譯後源程式**長度確定

函式呼叫不會使源程式變長。

#include 指令用於實現檔案的包含操作。

格式1:#include《檔名》

系統在編譯器系統指定的頭檔案目錄中找相應的檔案

格式2:#include"檔名"

系統首在當前源程式檔案所在目錄下找檔案,如果找不著

系統將在編譯器系統指定的頭檔案目錄中找相應的檔案

故,自定義的檔案應使用「 」

系統的檔案應使用<>

#ifdef … #else … #endif 用於測試乙個巨集是否已經定義。

指令格式:

#ifdef 識別符號

程式段1

#else

程式段2

#endif

如果 識別符號 已定義 則執行程式段1

否則執行程式段2

**演示:

#include

intmain()

#ifndef … #else … #endif 用測試乙個巨集沒有被定義

於#ifdef … #else … #endif 相對

指令格式:

#ifndef 識別符號

程式段1

#else

程式段2

#endif

如果 識別符號 已定義 則執行程式段2

否則執行程式段1

**演示:

#include

intmain()

指令格式:

#if 表示式

程式段1

#else

程式段2

#endif

表示式為真 執行程式段1

否則執行程式段2

#include

intmain()

指令格式:

#if 表示式

程式段1

#elif 表示式

程式段2

#elif 表示式

程式段3

… …#else

程式段4

#endif

#elif的個數不限,但是必須有#else,類似於多分支結構

**演示:

#include

intmain()

用於輸出編譯錯誤資訊

常與條件編譯一起使用

若#error 指令 被執行則,則編譯器會終止編譯

指令格式:

#error 錯誤資訊

**演示:

int

main()

#pragma once 可以防止同一段**被包含多次

其實#pragma 指令的用法還有很多

檔案出錯時更改時,更改出錯資訊

**演示1:

int

main()

錯誤結果:

**演示2:

int

main()

#用於實現文字替換

##用於連線兩個標識串

**演示:

#include

#define print(name) printf("hello "#name"!");

//#name有單獨的雙引號

#define text(x,y) x##y

intmain()

異常:使用者的輸入或者程式的邏輯結構存在問題,都將造成程式執行結果出現錯誤,嚴重時會造成系統宕機,通常將這類問題定義為異常。

c語言本身沒有提供異常捕獲機制,故需要提高程式容錯能力來保證程式的穩定性。

c語言標頭檔案assert.h中定義了巨集assert用於斷言操作。

斷言是指假定當前結論正確,如果不正確,則程式會停止,並輸出錯誤資訊。

**演示:

#include

#include

intmain()

執行結果:

預編譯與編譯

一c c 源 從最初的文字變為可執行檔案主要進行三大步 預編譯階段 主要是編譯器執行 文字處理工作,並不會進行語法檢查 主要執行三大類預編譯命令 巨集定義 文字替換功能,將使用了巨集的地方採取巨集定義方式直接展開 條件編譯 文字剪下功能,根據設定的條件選擇性刪除一些 片段 包含檔案 文字插入功能 i...

編譯原理 預編譯 編譯 彙編與鏈結

我們編寫的程式 是怎樣執行起來的?到底執行的是什麼內容?平時我們所說的編譯主要包括預編譯 編譯 彙編與鏈結,這四部分分別都幹什麼工作,主要職能有哪些。講述編譯之前,我們先要了解程式記憶體。乙個由c c 編譯的程式占用的記憶體,大致分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式...

JDBC程式設計之預編譯SQL與防注入

在jdbc程式設計中,常用statement preparedstatement 和 callablestatement三種方式來執行查詢語句,其中 statement 用於通用查詢,preparedstatement 用於執行引數化查詢,而 callablestatement則是用於儲存過程。1 ...