為實現**的可移植性和可重用性,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 ...