第一章 編譯預處理

                課程目標git

瞭解嵌入式C語言編程特色和操做細節 結合嵌入式環境深刻理解指針、數組和函數 提升編程實踐和編程程序規範理解 熟悉C語言標準庫應用和特色github

 

                   課程結構圖express

            第一章編程

第一章數組

編譯預處理與位運算數據結構

編譯預處理與位運算函數

 

                                            本章目標3d

本章概述指針

講述宏定義的標準用法和位操做的基本應用調試

瞭解預編譯的概念,掌握宏定義的方法。

瞭解「文件包含」與預處理的應用。 瞭解條件編譯的幾種形式。

本章目標

瞭解一些C語言特殊的宏定義 重點

宏定義操做

 

                 本章結構

編譯預處理和位運算

編譯預處理和位運算 文件包含

 

編譯預處理 編譯預處理

宏定義 宏定義

文件包含

條件編譯 條件編譯

預處理其餘關鍵詞

預處理其餘關鍵詞

                  1 編譯預處理與位運算

編譯預處理

宏定義

文件包含

條件編譯

位運算

其餘預處理關鍵字

 

                                                      1.1編譯預處理 做用:對源程序編譯以前作一些處理,生成擴展C源程序

種類

格式:

#define #ifdef #ifndef #include #if--#else--#endif等

宏定義

文件包含

條件編譯

其餘宏定義 #line #error #pragma

「#」開頭 佔單獨書寫行 語句尾不加分號

 

               1.2 宏定義

#undef 無參數宏定義 有參數宏定義

 

                    1.2.1 #undef #undef定義指令刪除前面定義的宏名字。

表達通常形式爲:

例子

#undef macro-name

#define MICRO 1 #undef MICRO

 

                             1.2.2 無參數宏定義

宏體可缺省,表示宏名 定義過或取消宏體

不帶參數宏定義

通常形式: #define 宏名 [宏體] 功能:用指定標識符(宏名)代替字符序列(宏體)

如 #define YES 1

#define NO 0

#define PI 3.1415926

#define OUT printf(「Hello,World」);

例例#d#edfienfeineWWIDITDHTH8080 ()

#d#edfienfeineLELNEGNTGHTHWWIDITDHT+H4+040 v a v r =a r L = E L NE GN TG HT * H2 * ; 2 ;

if(x==YES) printf(「correct!\n」); ()

展開例後:#deifi(nxe==1P)I 3.14p1r5in9tf(「correct!\n」);

宏宏展展開開::vavr=ar8=0+8400+4*02;*2;

else if (x==NO) printf(「error!\n」);

prinetfl(s「e2*iPf (Ix==%=f0\n)」,PIp*r2in);tf(「error!\n」); 例 #define MAX MAX+10 (×)

宏展開:printf(「2*PI=%f\n」,3.14159*2); 嵌入式家園 www.embedclub.com

上海嵌入式家園-開發板商城 http://embedclub.taobao.com/

                                     1.2.2 不帶參數宏定義 宏定義的規則

宏名通常習慣用大寫字母表示,以便與變量名相區別 宏定義不是C語句,沒必要在行末加分號 在進行宏定義時,能夠引用已定義的宏名,能夠層層替換。 只做字符替換,不分配內存空間。

#define R 3.0

#define PI 3.1415926 結果:

#define L 2*PI*R #define S PI*R*R main()

{

L = 18.849556

}

嵌入式家園 www.embedclub.comprintf(「L=%f\nS=%f\n」,L,S);

上海嵌入式家園-開發板商城 http://embedclub.taobao.com/

結果:

L = 18.849556

S = 28.274333

S = 28.274333

                                       1.2.2 不帶參數宏定義 宏定義的特色

宏名通常習慣用大寫字母表示 提升程序的通用性 宏名的有效範圍爲定義命令以後到本源文件結束 能夠用#undef命令終止宏定義的做用域 宏定義只做簡單的替換,不做正確性檢查

 

             1.2.2 不帶參數宏定義 練習:

定義一個宏,用於計算一年當中的秒數。定義一

 個宏,用於計算一年當中的秒數。

 

                                       1.2.3 帶參數宏定義

通常形式: #define 宏名(參數表) 宏體

例 #define S(a,b) a*b ...........

不能加空格

area=S(3,2); 宏展開: area=3*2;

宏展開:形參用實參換,其它字符保留

宏體及各形參之間應加空格

注意宏體的括號

例 #define S (r) PI*r*r

例 #define POWER(x) x*x

至關於定義了不帶參宏S,表明字符串「(r) PI*r*r」 x=4; y=6;

z=POWER(x+y);

宏展開:z=x+y*x+y;

通常寫成: #define POWER(x) ((x)*(x))

宏展開: z=((x+y)*(x+y)); 嵌入式家園 www.embedclub.com

上海嵌入式家園-開發板商城 http://embedclub.taobao.com/

                                                   1.2.3 帶參數宏定義 帶參數宏定義的特色

帶參宏定義中,宏名和形參表之間不能有空格出現

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

寫爲: #define MAX (a,b) (a>b)?a:b 將被認爲是無參宏定義,宏名MAX表明字符串 (a,b)(a>b)?a:b

在帶參宏定義中,形式參數不分配內存單元,所以沒必要做類型定義

在宏定義中的形參是標識符,而宏調用中的實參能夠是表達式

#define SQ(y) (y)*(y) main()

{

int a,sq;

printf("input a number: ");

scanf("%d",&a);

sq=SQ(a+1);

printf("sq=%d\n",sq);

在宏定義中,字符串內的形參一般要用括號括起來以免出錯

}

 

                   1.2.3 帶參數宏定義 帶參的宏和帶參函數很類似,但有本質上的不一樣

帶參宏 處理時間 編譯時

函數 程序運行時

參數類型 處理過程

無類型問題

定義實參,形參類型 分配內存

不分配內存

簡單的字符置換

先求實參值,再代入形參 不變

變長 運行速度 不佔運行時間

程序長度

 

調用和返回佔時間

                           1.2.3 帶參數宏定義 帶參的宏和帶參函數很類似,但有本質上的不一樣

函數例 宏定義例

main() {

#define SQ(y) ((y)*(y))

int i=1;

while(i<=5) printf("%d\n",SQ(i++));

main() {

}

SQ(int y) {

int i=1; while(i<=5)

return((y)*(y)); }

printf("%d\n",SQ(i++)); }

 

                                         1.3 文件包含 功能:一個源文件可將另外一個源文件的內容所有包含進來

函數例

#include 「file2.c」 A

file2.c

嵌入式家園 www.embedclub.com

<> 直接按標準目錄搜索

「」 先在當前目錄搜索,再搜索標準目錄 通常形式: #include 「文件名」

或 #include <文件名> 處理過程:預編譯時,用被包含文件的內容取代該預處理命令,再對「包

含」後的文件做一個源文件編譯

上海嵌入式家園-開發板商城 http://embedclub.taobao.com/

B

A file1.c file1.c

file2.c

                                            1.3 文件包含

被包含文件內容 源文件(*.c) 頭文件(*.h)

file3.h

文件包含可嵌套

file1.c A

#include 「file2.h」

#include 「file3.h」

AB file1.c file2.h

file3.h

宏定義

數據結構定義

函數說明等

file2.h

 

C

              1.3 文件包含 例子

/* powers.h */

#define sqr(x) ((x)*(x))

#define cube(x) ((x)*(x)*(x)) #define quad(x) ((x)*(x)*(x)*(x))

#include <stdio.h>

#include "powers.h"

#define MAX_POWER 10 int main()

{ intn;

}

printf("%2d\t %3d\t %4d\t %5d\n",n,sqr(n),cube(n),quad(n)); 嵌入式家園 www.embedclub.com

printf("number\t exp2\t exp3\t exp4\n"); printf("----\t----\t-----\t------\n"); for(n=1;n<=MAX_POWER;n++)

上海嵌入式家園-開發板商城 http://embedclub.taobao.com/

                                1.3 文件包含 文件包含特色

一個include命令只能指定一個被包含文件

能夠用雙引號括起來,也能夠用尖括號括起來。

文件包含容許嵌套

被包含文件(file2.h)與其所在的文件(file.c)在預編譯以後已成爲同一個文 件

 

              1.4 條件編譯 #if、#else、#elif #endif

#ifdef和#ifndef

                1.4.1 #if#else#elif #endif 條件編譯指令中最經常使用的或許是#if,#else,#elif和#endif

#if的通常形式是:

#if constant-expression Statement sequence

#endif

#endif標記#if塊的結束 例子:

#ifdef COMPUTER_A #define INTEGER_SIZE 16

#else

# define INTEGER_SIZE 32

#endif

 

                1.4.1 #if#else#elif #endif 條件編譯指令中最經常使用的或許是#if,#else,#elif和#endif

#if的通常形式是:

#if constant-expression Statement sequence

#endif

#endif標記#if塊的結束 例子:

#ifdef COMPUTER_A #define INTEGER_SIZE 16

#else

# define INTEGER_SIZE 32

#endif

 

                1.4.1 #if#else#elif #endif #else指令的做用與C語言的else類似,#if指令失敗時它可

以做爲備選指令

#else既是標記#if塊的結束,也標記#else塊的開始

每一個#if只能寫一個#endif匹配

例子:

#include <stdio.h> #define MAX 100 int main(void)

{

}

#if MAX>99

printf(「Compiled for array greater than 99.\n」);

#else

printf(「Complied for small array.\n」);

#endif return 0;

 

              1.4.1 #if#else#elif #endif

#elif指令的意思是「不然,若是」

語法格式:

#if expression Statement sequence

#elif expression1 Statement sequence

#elif expression2 ......

#elif expression Statement sequence

#endif

 

                      1.4.2 #ifdef#ifndef #ifdef --若是已定義

#ifdef的通常形式以下: #ifdef 標識符

程序段1 #else

程序段2 #endif

當所指定的標識符已經被#define命令定義過,則在程序編譯階段只編譯 程序段1,不然編譯程序段2。

 

                      1.4.2 #ifdef#ifndef #ifndef --若是已定義

#ifdef的通常形式以下: #ifndef 標識符

程序段1 #else

程序段2 #endif

做用是當所指定的標識符未被#define命令定義過,則在程序編譯階段只 編譯程序段1,不然編譯程序段2。它只是第一行與第一種形式不一樣。這 種形式與第一種形式的做用相反#ifndef

 

            1.4.2 #ifdef#ifndef #ifdef和#ifndef

#inlucde <stdio.h> #define T 10

int main(void)

{

#ifdef T

printf(「Hi T\n」);

#else

printf(「Hi anyone\n」);

#endif #ifndef M

printf(「M Not Defined\n」); #endif

return 0; }

 

                      1.4.2 #ifdef#ifndef #if --若是已定義

#if 的通常形式以下: #if 常量表達式

程序段1 #else

程序段2 #endif

如常量表達式的值爲真(非0),則對程序段1 進行編譯,不然對程序段2進 行編譯

 

            1.4.2 #ifdef#ifndef #if 例子

#define R 1 main()

{

}

float c,r,s;

printf ("input a number: "); scanf("%f",&c);

#if R

r=3.14159*c*c;

printf("area of round is: %f\n",r); #else

s=c*c;

printf("area of square is: %f\n",s); #endif

 

            階段小節

  宏定義的特色和宏定義的取消   帶參數宏定義要注意的幾個細節

  條件編譯主要應用在那幾個方面,它有幾種使用方法  Include 包含文件的兩種方法和他們之間的區別特色

 

                  1.5 其餘預處理關鍵字

#error 使用defined #line #pragma

#和## 預約義宏

 

                               1.5.1 #error

#error指令強制編譯程序中止編譯

主要用於程序調試

#error指令的通常形式是 #error error-message

注意:

宏串error-message不用雙引號包圍 能夠自定義錯誤內容

 

                     1.5.2 使用defined 肯定是否認義宏名字的方法

defined操做符的通常形式如 defined macro-name

肯定宏MY是否認義:define與#ifdef: #if defined MY

#ifdef MY

感嘆號」!」來反轉相應的條件 #if !defined DEBUG

#endif

printf(「Final Version!\n」);

 

                    1.5.3 #line

#line指令改變__LINE__和__FILE__的內容 #line的通常形式

#line number 「filename」 主要用於調試和特殊應用

 

            1.5.4 ### 操做符#一般稱爲字符串化的操做符

#include <stdio.h> #define mkstr(s) #s int main(void)

{

}

printf(mkstr(I like C)); return 0;

預處理程序把如下的語句:

變成

printf(mkstr(I like C));

printf(「I like C」);

 

               1.5.5 ### 「##」能夠把兩個獨立的字符串鏈接成一個字符串

#include<stdio.h>

#define SORT(X) sort_function # # X int main(void)

}

{

結果:

結果:

char *array;

int elements,element_size;.

SORT(3) (array,elements,element_size);

SORT(3) 轉化爲sort_function3 SORT(3) 轉化爲sort_function3

SORT(3) (array,elements,element_size)轉化爲 SORT(3) (array,elements,element_size)轉化爲

sort_function3(array,elements,element_size sort_function3(array,elements,element_size

若是在運行時才能肯定要調用哪一個函數,能夠利用 「##」運算符動態地構造要調用函數的名稱。

 

                 1.5.6 預約義宏

__DATE__ 進行預處理的日期(「Mmm dd yyyy」形

式的字符串文字)

__FILE__ 表明當前源代碼文件名的字符串文字 __LINE__ 表明當前源代碼中的行號的整數常量 __TIME__ 源文件編譯時間,格式微「hh:mm:ss」 __func__ 當前所在函數名

 

              1.5.7 預約義宏 例子

#include <stdio.h> #include <stdlib.h> void why_me();

int main()

void why_me() {

{

printf( "The file is %s.\n", __FILE__ ); printf( "The date is %s.\n", __DATE__ ); printf( "The time is %s.\n", __TIME__ ); printf( "This is line %d.\n", __LINE__ ); printf( "This function is %s.\n",

printf( "This function is %s\n", __func__ ); printf( "The file is %s.\n", __FILE__ ); printf( "This is line %d.\n", __LINE__ );

__func__ ); why_me(); return 0;

}

 

}

            階段小節

  位操做幾個運算操做的特色   位段的特色和位段數據的引用

  位段使用的規則

  C語言擴展宏定義幾個具體應用

 調試

  ##與#   #define

 

                                本章結構

編譯預處理和位運算

編譯預處理和位運算

文件包含 文件包含

講述條件編譯的三種應用方式

   和主要功能實現

編譯預處理 編譯預處理

#define定義的原則和注意事項 及應用

宏定義 宏定義

條件編譯 條件編譯

預處理其餘關鍵詞

預處理其餘關鍵詞

 

預處理的基礎操做方式

講述文件包含的特色和用處, 以及#include」」<>的區別

講述了#error以及#pragma和 調試輸入基本應用

                本章總結

宏定義特色和注意細節 條件編譯特色和主要用處 文件包含的路徑查詢規則 C語言擴展宏定義的用法

 

                                       實驗1 題目

用宏定義來實現兩個數取最大值

注意事項

?運算符的運用 對參數的包含 define的語法特色

實驗結果

掌握宏定義的具體應用,深化對宏定義的操做。

 

 git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

相關文章
相關標籤/搜索