c語言程序指令
㈠ c語言中指令和語句有什麼區別
語句是由分號結束為標志,而指令是對某個動作的完成過程。一個語句可以由多個指令組成,指令是基本單位。打個比方程序中有:c=a+b,z=x*y;這里算是一個語句,只有一個分號,指令有兩個,是a+b的值賦給c,另一個是x*y的值賦給z。你可這樣理解。
㈡ 求大神整理c語言指令符號及用法大全。
編譯指令
編譯指令
說明
#include
包含另一個文件
#define
定義一個宏(macro)或是常量
#undef
取消一個宏常量的定義
#asm和#endasm
在程序中加入匯編語言的程序
#ifdef、#ifndef、#else、#endif
用於條件式的編譯
註解://—單行註解;
基本數據類型 (int,float,double,char,void)
數據類型
類型說明
長度(位)
數據長度
bit
位
1
0,1
char
字元
8
—128~127
unsigned char
無符號字元
8
0~255
signed char
有符號字元
8
—128~127
int
整型
16
—32768~32767
short int
短整型
16
—32768~32767
unsigned int
無符號整型
16
0~65535
signed int
有符號整型
16
—32768~32767
long int
長整型
32
—2147483648~2147483647
unsigned long int
無符號長整型
32
0~4294967295
signed long int
有符號長整形
32
—2147483648~2147483647
float
浮點數(實數)
32
0.175e-38~0.402e38
double
雙精度浮點
32
0.175e-38~0.402e38
void
空
0
沒任何數據
用戶自定義數據類型格式
typedef struct{
數據類型 變數序列1;
數據類型 變數序列1;
...
}自定義數據類型的名稱;
保留字
_at_,alien,bdata,break,bit,case,char,code,compact,const,continue,data,
default,do,double,far,else,enum,extern,float,for,goto,if,funcused,idata,int,
inline,interrupt,large,long,pdata,_priority_,reentrant,return,sbit,sfr,sfr16,
short,sigend,sizeof,small,static,struct,switchc_task_,typedef,using,union,
unsigned,void,volatile,while,xdata
常量表示法
常數
規則
範例
十進制
一般十進制格式
1234567890
二進制
開頭加上0b
0b00001110
八進制
開頭加上O
O0123
十六進制
開頭加上0x
0xFF45
無符號整數常量
結尾加上U
30000U
長整數常量
結尾加上L
299L
無符號長整數常量
結尾加上UL
327800UL
浮點數的常量
結尾加上F
4.234F
字元常量
以單引號括起來
『a』
字元串常量
以雙引號括起來
「hello」
-----------------------------------------------------運算符-----------------------------------------------------
算術運算
運算符
說明
範例
執行結果
+
加
c=a+b;
c 等於10
—
減
d=a—b;
d 等於6
*
乘
e=a*b;
e 等於16
/
除
f=a/b;
f 等於4
%
取余數
g=a%b;
g 等於0
++
加1
c++;相當於c=c+1;
c 等於11
——
減1
d——;相當於d=d—1;
d 等於5
=
等於
a=8;
設置a等於8
+=
先相加在等於
e+=5;相當於e=e+5;
e 等於21
—=
先相減在等於
f—=5;相當於f=f—5;
f 等於—1
*=
先相乘在等於
b*=5;相當於b=b*5;
b 等於0
/=
先相除在等於
a/=5;相當於a=a/5;
a 等於1
%=
先取余數在等於
a%=5;相當於a=a%5;
a 等於3
※假設a等於8,b等於2
比較運算
運算符
說明
範例
執行結果
==
等於
a==5
F
!=
不等於
a!=5
T
<<o:p>
小於
a<5
F
>
大於
a>5
T
<=
小於等於
a<=5
F
>=
大於等於
a>=5
T
※比較運算結果是個布爾值既TRUE(真值)或FALSE(假值)。假設a等於8
邏輯運算
運算符
說明
範例
執行結果
&&
AND
(a>5)&&(a<10)
T
||
OR
(a<5)||(a>10)
F
!
NOT
!(a>10)
T
※邏輯運算結果是個布爾值既TRUE(真值)或FALSE(假值)。假設a等於8
位邏輯運算
運算符
說明
範例
執行結果
&
AND
a&0x01
a等於1
|
OR
a|0x80
a等於0x85
~
NOT
~a
a等於0xFA
^
XOR
a^0xFF
a等於0xFA
<<
左移
a<<1
a等於0x0A
>>
右移
a>>1
a等於0x0A
※假設a等於5
----------------------------------------------------控制命令---------------------------------------------------
if語句
if(條件) 語句1;
else 語句2;
例:if(d==4) d=0; //如果d等於4就設置d等於0
else d++; //否則就將d加1
if(ticks==0) { //如果ticks等於0
ticks=1000; //ticks 設置成1000
counter[0]++; //counter[0]加1
}
嵌套if語句
例:if(counter[0]==10) {
counter[1]++;
counter[0]=0;
if(counter[1]==10) {
counter[2]++;
counter[1]=0;
}
}
switch語句
switch (變數) {
case 常量1:語句1; break;
case 常量2:語句2; break;
case 常量3:語句3; break;
......
default ; 語句n;
}
for循環
for (初值,條件,變化值) 語句;
例:for(i=0;i<10;i++) x=x+i;
for(i=1;i<10,i++)
for(j=1;j<10,j++)
printf(「%d %d」,i,j);
無窮循環:
for( ; ; );
while循環
while (條件) 語句;
例:while (ch!=!』A』) ch=getche();
無窮循環:
while(1);
do/while循環
do {
語句;
...
} while(條件);
例:do {
ch=getche();
} while (ch!=」A」);
goto語句
loop1:
x++;
if(x<100) goto loop1;
----------------------------------------------------指針和函數------------------------------------------------
指針的定義
數據類型 *指針變數的名字;
例: char *p;
int *x;
指針與數組
例: char filename[80];
char *p;
p=filename; //指針p存放filename的開始地址
int x[5]={1,2,3,4,5};
int *p,sum,i;
p=x; //指針p存放數組x的開始地址
for(i=0;i<5;i++)
sum=sum+p[i]; //p[i]相當於x[i]
指針的運算
1.針變數前面加上*號就是取得指針所指向位置的內容。
例:int x[5]={1,2,3,4,5};
int *p;
p=x; //指針p存放數組x的開始地址
*p=10; //相當於設置x[0]等於10
2.變數前面加上&符號,可以取得一個變數的位置。
例:int x,y;
int *p;
p=&x; //指針p存放x的地址,相當於p是指向x 的指針
*p=1; //相當於設置x等於1
3.&符號也可以加在數組的前面
例:int x[5];
int *p;
p=&x[2]; //指針p存放x[2]的地址,相當於p是指向x[2]的指針
*p=50; //相當於設置x[2]等於50
函數
函數類型 函數名稱(參數序列);
參數說明
{
函數的主體
}
例:void delay (void) { //不返回任何數據的函數
unsigned char i,j; //沒有任何參數的函數
for(i=0,i<255,i++)
for(j=0,j<255,j++);
}
main()
{
...
delay(); //調用函數
}
例:unsigned char sum(unsigned chat a,unsigned chat b)
{
unsigned chat x;
check_GLCD_busyflag(); //函數中可以調用另一個函數
x=a+b;
return x; //return會返回x的數據
}
中斷服務函數
void 中斷服務程序的名稱(void) interrupt 中斷號碼using 寄存器組號碼
{
中斷服務子程序主體
}
中斷號碼
#define IE0_VECTOR 0 //0x03
#define TF0_VECTOR 1 //0x0B
#define IE1_VECTOR 2 //0x13
#define TF1_VECTOR 3 //0x1B
#define SIO_VECTOR 4 //0x23
對於S51有定時器2
#define TF2_VECTOR 5 //0x2B
例:static void xint0_isr(void) interrupt IE0_VECTOR(或0) using 1
{
unsigned char i,j=0xFF;
for(i=0,i<16,i++)
{
j++;
P1=j; //將數值輸出到P1口
delay_4isr();
}
}
-----------------------------------------------------匯編語言--------------------------------------------------
在C中加入匯編語言
例:void delay100us()
{
#pragma asm
mov r7,#1
more: mov r3,#48
djnz r3,$
djnz r7,more
#pragma endasm
}
----------------------------------------------------宏(macro)----------------------------------------------
宏的定義
%*define (macro名稱) (macro的指令)
例:%*define (write_1) (
setb DI
serb SK
clr SK
)
#define 宏的名稱 宏的指令
例:#define uchar unsigned char
C語言中的符號總結
運算符的種類C語言的運算符可分為以下幾類;
1. 算術運算符
用於各類數值運算,包括加減乘除求余自增自減共七種運算
{ ( + ) ,( - ),(* ) ,( / ) ,( % ),( ++ ),(-- )}。
2. 關系運算符
用於比較運算,包括大於(>),小於(<</span>),等於(==),大於等於(>=),
小於等於(<=),不等於(!=)共六種。
3.邏輯運算符
用於邏輯運算,包括與(&&)或(||)非(!)三種.
4.位操作運算符
參與運算的量,按二進制位進行運算,包括:
位與(&),位或(|),位非(~),為異或(^),左移(<<),右移(>>)共六種。
5.賦值運算符
用於賦值運算,分為:
簡單賦值(=)
復合算術賦值(+=,-=,*=,/=,%=)
復合位運算賦值(&=,|=,^=,>>=,<<=)三類共十一種。
6.條件運算符
這是一個三目運算符,用於條件求值(?:)。
7.逗號運算符
用於把若干表達式組合成一個表達式(,)。
8.指針運算符
用於取內容(*)和取地址(&)兩種運算。
9.求位元組數運算符
用於計算數據類型所佔用的位元組數(sizeof)。
10.特殊運算符
有括弧(),下標[],成員(→, .)
1.C的數據類型
基本類型,構造類型,指針類型,空類型
2.基本類型的分類及特點
類型說明符 位元組 數值范圍
字元型char 1 C字元集
基本整型int 2 -32768~32767
短整型short int 2 -32768~32767
長整型 long int 4 -214783648~214783647
無符號型 unsigned 2 0~65535
無符號長整型 unsigned long 4 0~4294967295
單精度實型 float 4 3/4E-38~3/4E+38
雙精度實型 double 8 1/7E-308~1/7E+308
3.常量後綴
L或l 長整型
U或u 無符號數
F或f 浮點數
4.常量類型
整數,長整數,無符號數,浮點數,字元,字元串,符號常數,轉義字元。
5.數據類型轉換
a自動轉換
在不同類型數據的混合運算中,由系統自動實現轉換, 由少位元組類型向多位元組類型轉換。 不同類型的量相互賦值時也由系統自動進行轉換,把賦值號右邊的類型轉換為左邊的類型。
b強制轉換
由強制轉換運算符完成轉換。
6.運算符優先順序和結合性
一般而言,單目運算符優先順序較高,賦值運算符優先順序低。 算術運算符優先順序較高,關系和邏輯運算符優先順序較低。 多數運算符具有左結合性,單目運算符、三目運算符、 賦值
7.表達式
表達式是由運算符連接常量、變數、函數所組成的式子。 每個表達式都有一個值和類型。 表達式求值按運算符的優先順序和結合性所規定的順序進行。
表示輸出類型的格式字元 格式字元意義
d 以十進制形式輸出帶符號整數(正數不輸出符號)
o 以八進制形式輸出無符號整數(不輸出前綴O)
x 以十六進制形式輸出無符號整數(不輸出前綴OX)
u 以十進制形式輸出無符號整數
f 以小數形式輸出單、雙精度實數
e 以指數形式輸出單、雙精度實數
g 以%f%e中較短的輸出寬度輸出單、雙精度實數
c 輸出單個字元
s 輸出字元串
標志字元為-、+、#、空格四種,其意義下表所示:
標志格式字元 標 志 意 義
- 結果左對齊,右邊填空格
+ 輸出符號(正號或負號)空格輸出值為正時冠以空格,為負時冠以負號
# 對c,s,d,u類無影響;對o類, 在輸出時加前
綴o 對x類,在輸出時加前綴0x;對e,g,f 類當結果有小數時才給出小數點
格式字元串
格式字元串的一般形式為: %[*][輸入數據寬度][長度]類型 其中有方括弧[]的項為任選項。各項的意義如下:
1.類型
表示輸入數據的類型,其格式符和意義下表所示。
格式 字元意義
d 輸入十進制整數
o 輸入八進制整數
x 輸入十六進制整數
u 輸入無符號十進制整數
f或e 輸入實型數(用小數形式或指數形式)
c 輸入單個字元
s 輸入字元串
轉義字元
轉義字元是一種特殊的字元常量。轉義字元以反斜線」\」開頭,後跟一個或幾個字元。轉義字元具有特定的含義,不同於字元原有的意義,故稱「轉義」字元。例如,在前面各例題printf函數的格式串中用到的「\n」就是一個轉義字元,其意義是「回車換行」。轉義字元主要用來表示那些用一般字元不便於表示的控制代碼。
常用的轉義字元及其含義
轉義字元 轉義字元的意義
\n 回車換行
\t 橫向跳到下一製表位置
\v 豎向跳格
\b 退格
\r 回車
\f 走紙換頁
\\ 反斜線符」\」
\』 單引號符
\a 鳴鈴
\ddd 1~3位八進制數所代表的字元
\xhh 1~2位十六進制數所代表的字元
廣義地講,C語言字元集中的任何一個字元均可用轉義字元來表示。表2.2中的\ddd和\xhh正是為此而提出的。ddd和hh分別為八進制和十六進制的ASCII代碼。如\101表示字?quot;A」 ,\102表示字母」B」,\134表示反斜線,\XOA表示換行等。轉義字元的使用
在C語言中,對變數的存儲類型說明有以下四種:
auto 自動變數
register 寄存器變數
extern 外部變數
static 靜態變數
自動變數和寄存器變數屬於動態存儲方式, 外部變數和靜態變數屬於靜態存儲方式。在介紹了變數的存儲類型之後, 可以知道對一個變數的說明不僅應說明其數據類型,還應說明其存儲類型。 因此變數說明的完整形式應為: 存儲類型說明符 數據類型說明符 變數名,變數名…; 例如:
static int a,b; 說明a,b為靜態類型變數
auto char c1,c2; 說明c1,c2為自動字元變數
static int a[5]={1,2,3,4,5}; 說明a為靜整型數組
extern int x,y; 說明x,y為外部整型變數
與指針有關的各種說明和意義見下表。
int *p; p為指向整型量的指針變數
int *p[n]; p為指針數組,由n個指向整型量的指針元素組成。
int (*p)[n]; p為指向整型二維數組的指針變數,二維數組的列數為n
int *p() p為返回指針值的函數,該指針指向整型量
int (*p)() p為指向函數的指針,該函數返回整型量
int **p p為一個指向另一指針的指針變數,該指針指向一個整型量。
指針變數的賦值
p可以有以下兩種方式:
(1)指針變數初始化的方法 int a;
int *p=&a;
(2)賦值語句的方法 int a;
int *p;
p=&a;
(1)取地址運算符&
(2)取內容運算符*
㈢ c璇璦鐨勮煩杞鎸囦護鏄浠涔堬紵
C璇璦璺寵漿鎸囦護鍖呭惈錛屽瓙紼嬪簭璋冪敤錛屾棤鏉′歡杞縐伙紝鏉′歡杞縐葷瓑銆傚傦細
int x,y
x=10;
y=sqr(10);//姝ゆ椂灝嗚漿縐誨埌sqr鍑芥暟鍘繪墽琛岋紝涓哄瓙紼嬪簭璋冪敤鍙戠敓鐨勮煩杞
x=10;
goto sss;//姝ゆ椂灝嗚煩杞鍒皊ss寮濮嬫墽琛岋紝涓烘棤鏉′歡杞縐誨彂鐢熺殑璺寵漿
do{
i++;
}while(i<100) //褰搃灝忎簬100鏃跺皢璺寵漿鍒板驚鐜鐨勫紑濮嬬戶緇鎵ц岋紝涓烘潯浠惰漿縐
㈣ C語言預處理指令有哪些
我們可以在C源程序中插入傳給編譯程序的各中指令,這些指令被稱為預處理器指令,它們擴充了程序設計的環境。現把常用的預處理命令總結如下:
1. 預處理程序
按照ANSI標準的定義,預處理程序應該處理以下指令:
#if #ifdef #ifndef #else #elif
#endif
#define
#undef
#line
#error
#pragma
#include
顯然,上述所有的12個預處理指令都以符號#開始,,每條預處理指令必須獨佔一行。
2. #define
#define指令定義一個標識符和一個串(也就是字元集),在源程序中發現該標識符時,都用該串替換之。這種標識符稱為宏名字,相應的替換稱為宏代換。一般形式如下:
#define macro-name char-sequence
這種語句不用分號結尾。宏名字和串之間可以有多個空白符,但串開始後只能以新行終止。
例如:我們使用LEFT代表1,用RIGHT代表0,我們使用兩個#define指令:
#define LEFT 1
#define RIGHT 0
每當在源程序中遇到LEFT或RIGHT時,編譯程序都用1或0替換。
定義一個宏名字之後,可以在其他宏定義中使用,例如:
#define ONE 1
#define TWO ONE+ONE
#define THREE ONE+TWO
宏代換就是用相關的串替代標識符。因此,如果希望定義一條標准錯誤信息時,可以如下定義:
#define ERROR_MS 「Standard error on input \n」
如果一個串長於一行,可在行尾用反斜線」\」續行,如下:
#define LONG_STRING 「This is a very very long \
String that is used as an example」
3. #error
#error指令強制編譯程序停止編譯,它主要用於程序調試。#error指令的一般形式是:
#error error-message
注意,宏串error-message不用雙引號包圍。遇到#error指令時,錯誤信息被顯示,可能同時還顯示編譯程序作者預先定義的其他內容。
4. #include
程序中的#include指令要求編譯程序讀入另一個源文件。被讀入文件的名字必須用雙引號(「」)或一對尖括弧(<>)包圍,例如:
#include 「stdio.h」
#include <stdio.h>
都使C編譯程序讀入並編譯頭文件以用於I/O系統庫函數。
包含文件中可以包含其他#include指令,稱為嵌套包含。允許的最大嵌套深度隨編譯器而變。
文件名被雙括弧或尖括弧包圍決定了對指定文件的搜索方式。文件名被尖括弧包圍時,搜索按編譯程序作者的定義進行,一般用於搜索某些專門放置包含文件的特殊目錄。當文件名被雙括弧包圍時,搜索按編譯程序實時的規定進行,一般搜索當前目錄。如未發現,再按尖括弧包圍時的辦法重新搜索一次。
通常,絕大多數程序員使用尖括弧包圍標準的頭文件,雙引號用於包圍與當前程序相關的文件名。
5. 條件編譯指令
若干編譯指令允許程序員有選擇的編譯程序源代碼的不同部分,這種過程稱為條件編譯。
5.1#if、#else、#elif #endif
條件編譯指令中最常用的或許是#if,#else,#elif和#endif。這些指令允許程序員根據常數表達式的結果有條件的包圍部分代碼。
#if的一般形式是:
#if constant-expression
Statement sequence
#endif
如#if後的常數表達式為真,則#if和#endif中間的代碼被編譯,否則忽略該代碼段。#endif標記#if塊的結束。
#else指令的作用與C語言的else相似,#if指令失敗時它可以作為備選指令。例如:
#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;
}
注意,#else既是標記#if塊的結束,也標記#else塊的開始。因為每個#if只能寫一個#endif匹配。
#elif指令的意思是「否則,如果」,為多重編譯選擇建立一條if-else-if(如果-否則-如果鏈)。如果#if表達式為真,該代碼塊被編譯,不測試其他#elif表達式。否則,序列中的下一塊被測試,如果成功則編譯之。一般形式如下:
#if expression
Statement sequence
#elif expression1
Statement sequence
#elif expression2
Statement sequence
.
.
.
#elif expression
Statement sequence
#endif
5.2#ifdef和#ifndef
條件編譯的另一個方法是使用編譯指令#ifdef和#ifndef,分別表示「如果已定義」和「如果未定義」。#ifdef的一般形式如下:
#ifdef macro-name
Statement sequence
#endif
如果macro-name原先已經被一個#define語句定義,則編譯其中的代碼塊。
#ifndef的一般形式是:
#ifndef macro-name
Statement sequence
#endif
如果macro-name當前未被#define語句定義,則編譯其中的代碼塊。
我認為,用這種,可以很方便的開啟/關閉整個程序的某項特定功能。
#ifdef和#ifndef都可以使用#else或#elif語句。
#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;
}
6. #undef
#undef指令刪除前面定義的宏名字。也就是說,它「不定義」宏。一般形式為:
#undef macro-name
7. 使用defined
除#ifdef之外,還有另外一種確定是否定義宏名字的方法,即可以將#if指令與defined編譯時操作符一起使用。defined操作符的一般形式如下:
defined macro-name
如果macro-name是當前定義的,則表達式為真,否則為假。
例如,確定宏MY是否定義,可以使用下列兩種預處理命令之一:
#if defined MY
或
#ifdef MY
也可以在defined之前加上感嘆號」!」來反轉相應的條件。例如,只有在DEBUG未定義的情況下才編譯。
#if !defined DEBUG
Printf(「Final Version!\n」);
#endif
使用defined的一個原因是,它允許由#elif語句確定的宏名字存在。
8. #line
#line指令改變__LINE__和__FILE__的內容。__LINE__和__FILE__都是編譯程序中預定義的標識符。標識符__LINE__的內容是當前被編譯代碼行的行號,__FILE__的內容是當前被編譯源文件的文件名。#line的一般形式是:
#line number 「filename」
其中,number是正整數並變成__LINE__的新值;可選的「filename」是合法文件標識符並變成__FILE__的新值。#line主要用於調試和特殊應用。
9. #pragma
#pragma是編譯程序實現時定義的指令,它允許由此向編譯程序傳入各種指令。例如,一個編譯程序可能具有支持跟蹤程序執行的選項,此時可以用#pragma語句選擇該功能。編譯程序忽略其不支持的#pragma選項。#pragma提高C源程序對編譯程序的可移植性。
10. 預處理操作符#和##
有兩個預處理操作符:#和##,它們可以在#define中使用。
操作符#通常稱為字元串化的操作符,它把其後的串變成用雙引號包圍的串。例如:
#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」);
操作符##把兩個標記拼在一起,形成一個新標記。例如:
#include <stdio.h>
#define concat(a,a) a##b
int main(void)
{
Int xy = 10;
Printf(「%d」,concat(x,y));
Return 0;
}
預處理程序把以下語句:
Printf(「%d」,concat(x,y));
變成
Printf(「%d」,xy);
操作符#和##主要作用是允許預處理程序對付某些特殊情況,多數程序中並不需要。
11. 預定義宏
C規范了5個固有的預定義宏,它們是:
__LINE__
__FILE__
__DATE__
__TIME__
__STDC__
__LINE__和__FILE__包含正在編譯的程序的行號和文件名。
__DATE__和內容形如month/day/year(月/日/年)的串,代表源文件翻譯成目標碼的日期。
__TIME__中的串代表源代碼編譯成目標碼的時間,形如hour:minute:second(時:分:秒)
如果__STDC__的內容是十進制常數1,則表示編譯程序的實現符合標准C。
㈤ 關於C語言預處理命令
C程序的源代碼中可包括各種編譯指令,這些指令稱為預處理命令。雖然它們實際上不是C語言的一部分,但卻擴展了C程序設計的環境。本節將介紹如何應用預處理程序和注釋簡化程序開發過程,並提高程序的可讀性。ANSI標準定義的C語言預處理程序包括下列命令:
#define,#error,#include,#if,#else,#elif,#endif,#ifdef,#ifndef,#undef,#line,#pragma等。非常明顯,所有預處理命令均以符號#開頭,下面分別加以介紹。
一 #define
命令#define定義了一個標識符及一個串。在源程序中每次遇到該標識符時,均以定義的串代換它。ANSI標准將標識符定義為宏名,將替換過程稱為宏替換。命令的一般形式為:
#define identifier string
注意:
1該語句沒有分號。在標識符和串之間可以有任意個空格,串一旦開始,僅由一新行結束。
2宏名定義後,即可成為其它宏名定義中的一部分。
3 宏替換僅僅是以文本串代替宏標識符,前提是宏標識符必須獨立的識別出來,否則不進行替換。例如:
#define XYZ this is a tes
使用宏printf("XYZ");//該段不列印"this is a test"而列印"XYZ"。因為預編譯器識別出的是"XYZ"
4如果串長於一行,可以在該行末尾用一反斜杠' \'續行。
#defineLONG_STRING"this is a very long\
string that is used as an example"
5 C語言程序普遍使用大寫字母定義標識符。
6 用宏代換代替實在的函數的一大好處是宏替換增加了代碼的速度,因為不存在函數調用的開銷。但增加速度也有代價:由於重復編碼而增加了程序長度。
二 #error
命令#error強迫編譯程序停止編譯,主要用於程序調試。
#error指令使預處理器發出一條錯誤消息,該消息包含指令中的文本.這條指令的目的就是在程序崩潰之前能夠給出一定的信息。
三 #include
命令#i nclude使編譯程序將另一源文件嵌入帶有#include的源文件,被讀入的源文件必須用雙引號或尖括弧括起來。例如:
#include"stdio.h"或者#include<stdio.h>
這兩行代碼均使用C編譯程序讀入並編譯用於處理磁碟文件庫的子程序。
將文件嵌入#i nclude命令中的文件內是可行的,這種方式稱為嵌套的嵌入文件,嵌套層次依賴於具體實現。
如果顯式路徑名為文件標識符的一部分,則僅在那些子目錄中搜索被嵌入文件。否則,如果文件名用雙引號括起來,則首先檢索當前工作目錄。如果未發現文件,則在命令行中說明的所有目錄中搜索。如果仍未發現文件,則搜索實現時定義的標准目錄。
如果沒有顯式路徑名且文件名被尖括弧括起來,則首先在編譯命令行中的目錄內檢索。如果文件沒找到,則檢索標准目錄,不檢索當前工作目錄。
四 條件編譯命令
有幾個命令可對程序源代碼的各部分有選擇地進行編譯,該過程稱為條件編譯。商業軟體公司廣泛應用條件編譯來提供和維護某一程序的許多顧客版本。
#if、#else,#elif及#endif
#if的一般含義是如果#if後面的常量表達式為true,則編譯它與#endif之間的代碼,否則跳過這些代碼。命令#endif標識一個#if塊的結束。
#if constant-expression
statement sequence
#endif
Eg:
#define MAX 91
#include <iostream>
using namespace std;
int main()
{
#if MAX > 99
cout<<"MAX is bigger than 99"<<endl;
#elif MAX > 90
cout<<"MAX is bigger than 90"<<endl;
#else
cout<<"MAX is smaller than 90"<<endl;
#endif
return 0;
}
跟在#if後面的表達式在編譯時求值,因此它必須僅含常量及已定義過的標識符,不可使用變數。表達式不許含有操作符sizeof(sizeof也是編譯時求值)。
#else命令的功能有點象C語言中的else;#else建立另一選擇(在#if失敗的情況下)。注意,#else屬於#if塊。
#elif命令意義與ELSE IF 相同,它形成一個if else-if階梯狀語句,可進行多種編譯選擇。#elif 後跟一個常量表達式。如果表達式為true,則編譯其後的代碼塊,不對其它#elif表達式進行測試。否則,順序測試下一塊。
#if expression
statement sequence
#elif expression1
statement sequence
#endif
在嵌套的條件編譯中#endif、#else或#elif與最近#if或#elif匹配。
# ifdef 和# ifndef
條件編譯的另一種方法是用#ifdef與#ifndef命令,它們分別表示"如果有定義"及"如果無定義"。# ifdef的一般形式是:
# ifdef macroname
statement sequence
#endif
#ifdef與#ifndef可以用於#if、#else,#elif語句中,但必須與一個#endif。
#define MAX 91
#include <iostream>
using namespace std;
int main()
{
#ifdef MAX
cout<<"hello,MAX!"<<endl;
#else
cout<<"where is MAX?"<<endl;
#endif
#ifndef LEO
cout<<"LEO is not defined"<<endl;
#endif
return 0;
}
命令#undef 取消其後那個前面已定義過有宏名定義。一般形式為:
#undef macroname
命令#line改變__LINE__與__FILE__的內容,它們是在編譯程序中預先定義的標識符。命令的基本形式如下:
#line number["filename"]
其中的數字為任何正整數,可選的文件名為任意有效文件標識符。行號為源程序中當前行號,文件名為源文件的名字。命令#line主要用於調試及其它特殊應用。注意:在#line後面的數字標識從下一行開始的數字標識。
#line 100 "jia"
cout<<"#line change line and filename!"<<endl; //line 100
cout<<__LINE__<<endl; //101
cout<<__FILE__<<endl; //jia
五 #pragma
命令#pragma 為實現時定義的命令,它允許向編譯程序傳送各種指令。
#pragma的作用是設定編譯器的狀態或者是指示編譯器完成一些特定的動作。#pragma指令對每個編譯器給出了一個方法,在保持與C和C++語言完全兼容的情況下,給出主機或操作系統專有的特徵。依據定義,編譯指示是機器或操作系統專有的,且對於每個編譯器都是不同的。
其格式一般為: #Pragma Para
1 message 參數。
Message 參數能夠在編譯信息輸出窗口中輸出相應的信息,這對於源代碼信息的控制是非常重要的。其使用方法為:
#pragma message(「消息文本」)
當編譯器遇到這條指令時就在編譯輸出窗口中將消息文本列印出來。
當在程序中定義了許多宏來控制源代碼版本的時候,自己有可能都會忘記有沒有正確的設置這些宏,此時可以用這條指令在編譯的時候就進行檢查。假設希望判斷自己有沒有在源代碼的什麼地方定義了_X86這個宏可以用下面的方法
#ifdef _X86
#pragma message(「_X86 macro activated!」)
#endif
當定義了_X86這個宏以後,應用程序在編譯時就會在編譯輸出窗口裡顯示「_
X86 macro activated!」。就不會因為不記得自己定義的一些特定的宏而抓耳撓腮了。
2 code_seg 參數。
格式如:
#pragma code_seg( ["section-name"[,"section-class"] ] )
它能夠設置程序中函數代碼存放的代碼段,當開發驅動程序的時候就會使用到它。
3 #pragma once (比較常用)
只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次。這條指令實際上在VC6中就已經有了,但是考慮到兼容性並沒有太多的使用它。
4 #pragma hdrstop
表示預編譯頭文件到此為止,後面的頭文件不進行預編譯。BCB可以預編譯頭文件以加快鏈接的速度,但如果所有頭文件都進行預編譯又可能占太多磁碟空間,所以使用這個選項排除一些頭文件。
有時單元之間有依賴關系,比如單元A依賴單元B,所以單元B要先於單元A編譯。你可以用#pragma startup指定編譯優先順序,如果使用了#pragma package(smart_init) ,BCB就會根據優先順序的大小先後編譯。
5 #pragma resource "*.dfm"
表示把*.dfm文件中的資源加入工程。*.dfm中包括窗體外觀的定義。
6 #pragma warning( disable : 4507 34; once : 4385; error : 164 )
等價於:
#pragma warning(disable:4507 34) /* 不顯示4507和34號警告信息。如果編譯時總是出現4507號警告和34號警告, 而認為肯定不會有錯誤,可以使用這條指令。*/
#pragma warning(once:4385) // 4385號警告信息僅報告一次
#pragma warning(error:164) // 把164號警告信息作為一個錯誤。
同時這個pragma warning 也支持如下格式:
#pragma warning( push [ ,n ] )
#pragma warning( pop )
這里n代表一個警告等級(1---4)。
#pragma warning( push )保存所有警告信息的現有的警告狀態。
#pragma warning( push, n)保存所有警告信息的現有的警告狀態,並且把全局警告等級設定為n。
#pragma warning( pop )向棧中彈出最後一個警告信息,在入棧和出棧之間所作的一切改動取消。例如:
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
//.......
#pragma warning( pop )
在這段代碼的最後,重新保存所有的警告信息(包括4705,4706和4707)。
7 pragma comment(...)
該指令將一個注釋記錄放入一個對象文件或可執行文件中。
常用的lib關鍵字,可以幫連入一個庫文件。
8 progma pack(n)
指定結構體對齊方式。#pragma pack(n)來設定變數以n位元組對齊方式。
n 位元組對齊就是說變數存放的起始地址的偏移量有兩種情況:
第一、如果n大於等於該變數所佔用的位元組數,那麼偏移量必須滿足默認的對齊方式,
第二、如果n小於該變數的類型所佔用的位元組數,那麼偏移量為n的倍數,不用滿足默認的對齊方式。
結構的總大小也有個約束條件,分下面兩種情況:如果n大於所有成員變數類型所佔用的位元組數,那麼結構的總大小必須為佔用空間最大的變數佔用的空間數的倍數; 否則必須為n的倍數。
下面舉例說明其用法。
#pragma pack(push) //保存對齊狀態
#pragma pack(4)//設定為4位元組對齊
struct test
{
char m1;
double m4;
int m3;
};
#pragma pack(pop)//恢復對齊狀態
為測試該功能,可以使用sizeof()測試結構體的長度!
㈥ C語言中很多的預處理指令include、define等等它們各自的意義分別是什麼
include的作用: #include叫做「文件包含」 / include 語句包含並運行指定文件。 功能:它的功能是用來指定文件的全部內容替換程序中的命令行,從而使指定的文件與當前源文件連成一個源文件 書寫格式: #include <文件名> //表示編譯系統根據系統頭文件存放的目錄路徑去搜索系統頭文件,而不是在源文件目錄去查找 #include "文件名" //表示編譯系統首先在當前的源文件目錄中查找,若未找到才根據系統的頭文件存放的目錄路徑去搜索系統頭文件 //系統定義的頭文件通常使用尖括弧;用戶自定義的頭文件通常使用雙引號。 //一般來說,如果為調用庫函數而用#include命令來包含相關的頭文件,則用尖括弧,以節約查找時間。 //如果要包含的是用戶自己編寫的文件(這種文件一般都在用戶當前的目錄中),一般用雙撇號。 //若文件不在當前目錄中,在雙撇號內應該給出文件路徑(如#include"C:\wang\file2.h") ----------------- 1.#define 的作用 在C或C++語言源程序中允許用一個標識符來表示一個字元串,稱為「宏」。被定義為「宏」的標識符稱為「宏名」。在編譯預處理時,對程序中所有出現的「宏名」,都用宏定義中的字元串去代換,這稱為「宏代換」或「宏展開」。宏定義是由源程序中的宏定義命令完成的。宏代換是由預處理程序自動完成的。 在C或C++語言中,「宏」分為有參數和無參數兩種。 2. 無參宏定義 無參宏的宏名後不帶參數。 其定義的一般形式為: #define 標識符 字元串 其中的「#」表示這是一條預處理命令。凡是以「#」開頭的均為預處理命令。「define」為宏定義命令。「標識符」為所定義的宏名。「字元串」可以是常數、表達式、格式串等。 例如: #define M (a+b) 它的作用是指定標識符M來代替表達式(a+b)。在編寫源程序時,所有的(a+b)都可由M代替,而對源程序作編譯時,將先由預處理程序進行宏代換,即用(a+b)表達式去置換所有的宏名M,然後再進行編譯。 程序1: #define M (a+b) main(){ int s,y; printf("input a number: "); scanf("%d",&y); s=M*M; printf("s=%d\n",s); } 上常式序中首先進行宏定義,定義M來替代表達式(a+b),在 s= M * M 中作了宏調用。在預處理時經宏展開後該語句變為: S=(a+b)*(a+b) 但要注意的是,在宏定義中表達式(a+b)兩邊的括弧不能少。否則會發生錯誤。 如當作以下定義後:#difine M (a)+(b) 在宏展開時將得到下述語句:S= (a)+(b)*(a)+(b) 對於宏定義還要說明以下幾點: 1. 宏定義是用宏名來表示一個字元串,在宏展開時又以該字元串取代宏名,這只是一種簡單的代換,字元串中可以含任何字元,可以是常數,也可以是表達式,預處理程序對它不作任何檢查。如有錯誤,只能在編譯已被宏展開後的源程序時發現。 2. 宏定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起置換。 3. 宏定義必須寫在函數之外,其作用域為宏定義命令起到源程序結束。如要終止其作用域可使用#undef命令。 3. 帶參宏定義 c語言允許宏帶有參數。在宏定義中的參數稱為形式參數,在宏調用中的參數稱為實際參數。對帶參數的宏,在調用中,不僅要宏展開,而且要用實參去代換形參。 帶參宏定義的一般形式為: #define 宏名(形參表) 字元串 在字元串中含有各個形參。 帶參宏調用的一般形式為: 宏名(形參表) 例如: #define M(y) ((y)*(y)+3*(y)) /*宏定義*/ .... k=M(5); /*宏調用*/ .... 在宏調用時,用實參5去代替形參y,經預處理宏展開後的語句為: k=5*5+3*5 程序2: #define MAX(a,b) (a>b)?a:b main(){ int x,y,max; printf("input two numbers: "); scanf("%d%d",&x,&y); max=MAX(x,y); printf("max=%d\n",max); } 上常式序的第一行進行帶參宏定義,用宏名MAX表示條件表達式(a>b)?a:b,形參a,b均出現在條件表達式中。程序第七行max=MAX(x,y)為宏調用,實參x,y,將代換形參a,b。宏展開後該語句為: max=(x>y)?x:y; 用於計算x,y中的大數。