编译预处理
- #開頭,編譯預處理指令。? ? 不是C的語言
- #define?定義一個宏
1,宏的定義
#define?宏名? 宏的值? ? ? ? ?//值可以是任意的
#include <stdio.h>
#define P printf("你好\n")
#define wenzi "哈哈哈\n"
#define num 5
int main(){P;printf(wenzi);printf("%d",num+2);return 0;
}輸出:
你好
哈哈哈
7
?2,宏的特點
- 注釋不會被當作宏的一部分
- 宏的定義可以嵌套
- \? 若一個宏的值超過一行。該行未結束,與下一行連成一個整體
#include <stdio.h>
#define P "你好\
大家好\n"
#define num 5
#define num_1 num+5 //嵌套定義
int main(){printf(P);printf("%d\n",num);printf("%d",num_1);return 0;
}輸出:你好大家好
5
10
定義沒有值的宏
#define num? ? ??用于條件編譯
預定義的宏
例如:·_LINE_·? ??
3,帶參數的宏
#define num(x) ((x)*(x)*(x))
#define min(a,b) (a>b?b:a)
#define? cbb (x*123)
#define (x)*123
不推薦的
定義原則:
- 整個宏的值都有括號
- 每個參數都有括號?
#include <stdio.h>
#define min(a,b) (a>b?b:a)
#define num(x) ((x)*(x)*(x))
int main(){printf("min=%d\n",min(7,4));printf("%d",num(5));return 0;
}min=4
125
4,#include
把函數原型放到一個頭文件(以.h結尾)中,在需要調用這個函數的源代碼文件(.c文件)中#include這個頭文件,就能讓編譯器在編譯的時候知道函數的原型.
(1)#include?作用
- 把函數原型放到一個頭文件(以.h結尾)中,在需要調用這個函數的源代碼文件(.c文件)中#include這個頭文件,就能讓編譯器在編譯的時候知道函數的原型
- 它把那個文件的全部文本內容原封不動地插入到它所在的地方
- ·所以也不是一定要在.c文件的最前面#include
(2)兩種include方法區別
- #include有兩種形式來指出要插入的文件
- “ ”要求編譯器首先在當前目錄(.c文件所在的目錄)尋找這個文件,如果沒有,到編譯器指定的目錄六找
- <>讓編譯器只在指定的目錄去找
使用 " "? 使自己定義的頭文件
<>是系統給的頭文件
#incldue <stdio.h>
#include "max.h"
(3)頭文件使用
- 在使用和定義這個函數的地方都應該#include這個頭文件
- 一般的做法就是任何.c(源代碼文件,main()函數除外)都有對應的同名的.h(頭文件),把所有對外公開的函數的原型和全局變量的聲明都放進去
(4)不對外公開
- 在函數前面加上static就使得它成為只能在所在的編譯單元中被使用的函數
- 在全局變量前面加上static就使得它成為只能在所在的編譯單元中被使用的全局變量
(5)#include誤區
-
#include?不是用來引入庫的
-
stdio.h?頭文件中,只有printf()函數原型,用來保證參數正確輸入
5,聲明
int i;? ?定義變量
extern int i;? 聲明變量
int max(int a,int b);? 聲明函數
聲明不是產生代碼的東西,定義才是
聲明只是告訴你一下,讓你知道
只有聲明可以被放入頭文件中
(1)重復聲明
- 同一個編譯單元里,同名的結構不能被重復聲明如果你的頭文件里有結構的聲明,很難這個頭文件不會在一個編譯單元里被#include多次
- ?所以需要“標準頭文件結構”
(2)標準頭文件結構
運用條件編譯和宏,保證這個頭文件在一個編譯單元中只會被#include一次
?如果 _LIST_HEAD_? 沒有被定義,則定義它。若定義了,就不管
以下有關宏替換的敘述不正確的是(D )。A. 宏替換不占用運行時間。 B. 宏名無類型。 C. 宏替換只是字符替換。 D. 宏名必須用大寫字母表示。
A.占用編譯時間,不占用程序運行時間
D.建議宏名用大寫字母表示
以下正確的敘述是( D)。
A.宏定義不能出現在函數內部
B.在程序的一行中可以出現多個有效的預處理命令行
C.使用帶參數宏定義時,參數的類型應與宏定義時一致
D.宏替換不占用運行時間,只占用編譯時間
B.不可以
C.宏沒有參數
在一個C源程序文件中,若要定義一個只允許本源文件中所有函數使用的全局變量,則該變量需要使用的存儲類別是(D)
A.extern
B.register
C.auto
D.static
本源文件指的是? .c文件? ? ? ?一個程序中會有多個.c文件。本源文件單指一個.c文件
凡是函數中未指定存儲類別的局部變量,其隱含的存儲類型為(B )。
A.靜態(static)
B.自動(auto)
C.外部(extern)
D.寄存器(register)
忘了在程序開頭寫#include <stdio.h>,但是main()中的printf("hello\n");還是通過了編譯而且運行正確。說明為什么會這樣,并舉出例子說明什么情況下不#include相應的頭文件會通過編譯但是不能正確運行?
即使沒有include這個頭文件,編譯器仍然把它鏈接進去了。
比如一個函數的原型中,變量與返回值都是double類型,但是卻沒有include相應的頭文件,此時編譯器會默認變量與返回值的類型都是int類型,然后通過了編譯,但運行時就會出現錯誤。
總結
- 上一篇: 给定n本书的名称和定价,本题要求编写程序
- 下一篇: 苹果换屏要多少钱啊?