㈠ 預處理命令在書寫格式上有什麼要求
摘要 預處理指令是以#號開頭的代碼行。#號必須是該行除了任何空白字元外的第一個字元。#後是指令關鍵字,在關鍵字和#號之間允許存在任意個數的空白字元。整行語句構成了一條預處理指令,該指令將在編譯器進行編譯之前對源代碼做某些轉換。下面是部分預處理指令:
㈡ C語言有效的預處理命令總是以什麼開頭
C語言中,所有預處理命令都是以「#」號開頭的。
C語言程序設計預處理的概念:在編譯之前進行的處理。 C語言的預處理主要有三個方面的內容:宏定義、文件包含、條件編譯。
(2)編譯預命令必須以什麼開頭擴展閱讀:
1、宏定義:正確的宏定義是#defineS(r) ((r)*(r))
(1)宏名和參數的括弧間不能有空格
(2)宏替換只作替換,不做計算,不做表達式求解
(3)函數調用在編譯後程序運行時進行,並且分配內存。宏替換在編譯前進行,不分配內存
(4)宏的啞實結合不存在類型,也沒有類型轉換。
(5)宏展開使源程序變長,函數調用不會
(6)宏展開不佔運行時間,只佔編譯時間,函數調用占運行時間(分配內存、保留現場、值傳遞、返回值)。
2、文件包含:格式:#include "文件名"或#include <文件名>;編譯時以包含處理以後的文件為編譯單位,被包含的文件是源文件的一部分。編譯以後只得到一個目標文件.obj,被包含的文件又被稱為「標題文件」或「頭部文件」、「頭文件」,並且常用.h作擴展名。
3、條件編譯
格式:
(1)#ifdef 標識符 程序段1 #else 程序段2 #endif 或#ifdef 程序段1 #endif;
(2)#ifndef標識符 #define 標識1 程序段1 #endif;
(3)#if表達式1 程序段1 #elif 表達式2 程序段2 …… #elif 表達式n 程序段n #else 程序段n+1 #endif。
使用條件編譯可以使目標程序變小,運行時間變短。
㈢ 常見的預處理命令有哪兩種
很多小夥伴在自己寫代碼的時候,已經多次使用過include命令。使用庫函數之前,應該用include引入對應的頭文件。其實這種以#號開頭的命令稱為預處理命令。
C語言源文件要經過編譯、鏈接才能生成可執行程序:
1) 編譯(Compile)會將源文件(.c文件)轉換為目標文件。對於 VC/VS,目標文件後綴為.obj;對於GCC,目標文件後綴為.o。
編譯是針對單個源文件的,一次編譯操作只能編譯一個源文件,如果程序中有多個源文件,就需要多次編譯操作。
2) 鏈接(Link)是針對多個文件的,它會將編譯生成的多個目標文件以及系統中的庫、組件等合並成一個可執行程序。
關於編譯和鏈接的過程、目標文件和可執行文件的結構、.h 文件和 .c 文件的區別,我們將在後期專題中講解。
在實際開發中,有時候在編譯之前還需要對源文件進行簡單的處理。例如,我們希望自己的程序在 Windows 和 Linux 下都能夠運行,那麼就要在 Windows 下使用 VS 編譯一遍,然後在 Linux 下使用 GCC 編譯一遍。但是現在有個問題,程序中要實現的某個功能在 VS 和 GCC 下使用的函數不同(假設 VS 下使用 a(),GCC 下使用 b()),VS 下的函數在 GCC 下不能編譯通過,GCC 下的函數在 VS 下也不能編譯通過,怎麼辦呢?
這就需要在編譯之前先對源文件進行處理:如果檢測到是 VS,就保留 a() 刪除 b();如果檢測到是 GCC,就保留 b() 刪除 a()。
這些在編譯之前對源文件進行簡單加工的過程,就稱為預處理(即預先處理、提前處理)。
預處理主要是處理以開頭的命令,例如include <stdio.h>等。預處理命令要放在所有函數之外,而且一般都放在源文件的前面。
預處理是C語言的一個重要功能,由預處理程序完成。當對一個源文件進行編譯時,系統將自動調用預處理程序對源程序中的預處理部分作處理,處理完畢自動進入對源程序的編譯。
編譯器會將預處理的結果保存到和源文件同名的.i文件中,例如 main.c 的預處理結果在 main.i 中。和.c一樣,.i也是文本文件,可以用編輯器打開直接查看內容。
C語言提供了多種預處理功能,如宏定義、文件包含、條件編譯等,合理地使用它們會使編寫的程序便於閱讀、修改、移植和調試,也有利於模塊化程
㈣ 預編譯命令行由什麼符號開頭
#include "stdio.h"
#define P 3
void *F(int x)/*定義一個無類型函數,它有返回值,只是返回的值是指向無類型數據的指針*/
void main(){printf("%d\n",(int)F(1+3));/*將無類型函數F返回的指針值通過(int)強制轉換為int型*/
還有幾個問題,
1.預處理命令行必須位於源文件的開頭是對是錯?為什麼?
對!
編譯器在編譯源代碼時都是從開頭到結尾依次讀取,自己定義的變數、宏等等都得放前面,這樣在編譯器在讀到它們時就作一個記錄;
在使用這些變數、宏時,編譯器會在記錄中去尋找,如果找不到就會報錯——此變數未被定義。
函數可以放在結尾(main()之後),但是必須在開頭作一個函數聲明(也叫函數原型)以使編譯器為它作記錄,以便以後使用它時可以在記錄中找到它。
函數也可以放在前面(main()之前),此時就不用再聲明了,編譯器在讀到它時也會作一個記錄。
總之,自己定義的東西都得先聲明後使用,否則使用時在記錄中會找不到它。
預處理命令也是自己定義的東西,同屬這一范疇。
2.為什麼在源文件的一行上不能有多條預處理命令?
每條C語句都有一個「;」作結尾,即使都放一行,編譯器都能分辨得出。
預處理命令並不以「#」作為結尾標記,放一行的話編譯器是無法分辨的,它會把此行作為一個語句處理
通常的語句最好都分行寫,否則程序量大時是不便排錯的。
3.若有下列說明和定義
union dt
date;
變數data所佔內存位元組數與成員c所佔位元組數相同,為什麼?
聯合體的長度是其最長成員(如double c)的長度。
聯合體在內存中的存儲形式:
聯合體所有成員a,b,c都是同一地址,也就是說他們共同佔用這一段內存。
以TC3.0為例,a占這一段內存的頭2個位元組,b占這一段內存的頭一個位元組,c占這一段內存的全部位元組(也就是頭4個位元組)
4.為什麼以下不對
char *sp;*sp="right!";
char s[10];s="right!";
一、進行字元串賦值時可以在定義時:直接在字元串定義後接「="right"」
如:char *sp="right";
或者 char s[10]="right";
二、也可以在非定義時,這時左值必須是左值必須是字元串指針變數。
如:sp="right!";
以下都是錯誤用法:
*sp="right!";//左值不是字元串指針變數
s="right!";//左值只是字元串指針 常量
1、如果說*a包含(x和\0),而*b包含(x和y),拿*a-*b會得出什麼結果,*a和*b都是char型變數的話
最終的表達式*a-*b中,a points to '\0',b points to 'y',so 表達式*a-*b代表的是'\0'-'y',結果是-121(y的ASCII是121)
point(char*p)
main()
{
char b[4]={'a','b','c','d'),*p=b;
point(p); printf("%c\n",*p);
}
A.a B.b C.c D.d
選哪個?為什麼?
選D,p最初是首地址b,然後p是b+3,此時*p相當*(b+3)、b[3].
2號問題:
main()
,,,},i,j;
for(i=0;i<4;i++)
{for (j=0;j<i,j++)
printf("%4c",' ');/*原題就是'和'之間只有個空格,我也不清楚是怎麼回事*/
for(j=__;j<4;j++)
printf(%4d",num[i][j]);
printf("\n");
}
}
printf("%4c",' '); 其中的' '其實是一個空格字元常量,這個同'a','b','c'等字元常量是一樣的。
這個語句中%4c是指要讀取一個字元(這個字元就是後面的空格字元常量' ')並輸出,這個字元在顯示器上應該佔4格。所以此句的功能是輸出4個空格(空格也是屬於字元)。
你改成printf("%4c",'a');printf("%4c",'b');試下,它是輸出3個空格和一個字元。
printf("%8c",' ');是輸出8個空格,這個比printf(" ");來實現輸出8個字元來得方便。
若要按下列形式輸出數組右上半三角(什麼玩意?)。
1 2 3 4 i=0,j=i,那麼j可以是0,1,2,3
6 7 8 i=1,j=i,那麼j可以是1,2,3
11 12 i=2,j=i,那麼j可以是2,3
16 i=3,j=i,那麼j可以是3
則下劃線處應填入的是?為什麼?(B)
A.i-1 B.i
C.i+1 D.4-i
3號問題:
程序中若有下列說明和定義語句:
char fun(char*);
main()
{
char *s="one",a[5]=,(*fl)()=fun,ch;
......
}
下列選項中對函數的正確調用語句是?為什麼?
A.(*fl)(a);
B.*fl(*s);
C.fun(&a);
D.ch=*fl( s);
選擇A,根據定義char fun(char*),形參必須是一個字元指針,"a","s"才是字元指針(char pointer),而"*s" is char variable,"&a" is invalid.所以排除B、C
只有fun、*fl才是函數入口地址.
B.*fl(*s);相當於*(fl(*s)),錯誤,指針運算符只能針對指針運算,fl(*s)得到的是int,不是指針,下同。故排除B、D.
D.*fl( s);相當於*(fl( s));
4號問題
#define S(x) 4*x*x+1
main()
{
int i=6,j=8;
printf("%d",S(i+j));
getchar();
}
這個函數的輸出結果是多少?怎麼得的?
得到81.
因為S(i+j)經過預編譯用i+j替換x後,它被展開為4*i+j*i+j+1。即(4*6+8*6+8+1)
你應該這樣改:
#define S(x) 4*(x)*(x)+1
或者 printf("%d",S((i+j)));即將i+j用括弧括起來(i+j),這樣就在替換時用(i+j)替換x
㈤ 為什麼A是對的,預處理命令行都必須以#號開始 才是對的把
因為如果代碼是注釋它就不起作用了。
如/*注釋#define。
B、預處理命令行不可以 宏定義是可以的。
C、程序在執行過程中對預處理命令行進行處理。是在執行過程之前,所以才稱為預處理,就是先於程序處理的意思,這是對的。
宏定義又稱為宏代換、宏替換,簡稱「宏」。格式:#define標識符文本,其中的標識符就是所謂的符號常量,也稱為「宏名」。
D、對預處理命令行的處理是在編譯之前完成的,不是程序執行的過程中,選D。
正確的宏定義是#define S(r) ((r)*(r))
(2)宏名和參數的括弧間不能有空格
(3)宏替換只作替換,不做計算,不做表達式求解
(4)函數調用在編譯後程序運行時進行,並且分配內存。宏替換在編譯前進行,不分配內存
(5)宏的啞實結合不存在類型,也沒有類型轉換。
(6)宏展開使源程序變長,函數調用不會
(7)宏展開不佔運行時間,只佔編譯時間,函數調用占運行時間(分配內存、保留現場、值傳遞、返回值)。
㈥ 編譯預處理命令中什麼字元作為首字元
#include "stdio.h",#define P 3。void *F(int x)/*定義一個無類型函數,它有返回值,只是返回的值是指向無類型數據的指針*/
void main(){printf("%d
",(int)F(1+3));/*將無類型函數F返回的指針值通過(int)強制轉換為int型*/
編譯器在編譯源代碼時都是從開頭到結尾依次讀取,自己定義的變數、宏等等都得放前面,這樣在編譯器在讀到它們時就作一個記錄;在使用這些變數、宏時,編譯器會在記錄中去尋找,如果找不到就會報錯——此變數未被定義。函數可以放在結尾(main()之後),但是必須在開頭作一個函數聲明(也叫函數原型)以使編譯器為它作記錄,以便以後使用它時可以在記錄中找到它。
函數也可以放在前面(main()之前),此時就不用再聲明了,編譯器在讀到它時也會作一個記錄。總之,自己定義的東西都得先聲明後使用,否則使用時在記錄中會找不到它。預處理命令也是自己定義的東西,同屬這一范疇。
㈦ C++中預處理指令是什麼
C++中,預處理命令是以#號開頭,結尾沒有分號的命令行。這些命令會在編譯開始前由編譯器執行。有三種預處理命令:
1. 宏定義;
2. 文件包含;
3. 條件編譯。
宏定義命令格式為:
#define 標識符 替換文本
其中"標識符"稱為宏名,替換文本可以是任意的字元串。執行宏替換時編譯器將全部的宏名替換為替換文本。
文件包含命令格式為:
#include <文件名> 或#include "文件名"
文件名用尖括弧或雙引號括起來都是合法的。一般預設頭文件用尖括弧,自定義頭文件用雙引號。原因:用雙引號會先在當前目錄下查找。
條件編譯命令有很多種格式,這里只列出並解釋其中兩種:
格式1:
#ifdef 標識符
程序段1
#else
程序段2
#endif
它的意思是:如果標識符已經被宏定義,則編譯程序段1,否則編譯程序段2。
格式2:
#ifndef 標識符
程序段1
#else
程序段2
#endif
它的意思是:如果標識符沒有被宏定義,則編譯程序段1,否則編譯程序段2。
㈧ 預處理命令行必須位於C源程序的起始位置嗎
預處理命令是以「#」號開頭的命令,它們不是C語言的可執行命令,這些命令應該在函數之外書寫,一般在源文件的最前面書寫,稱為預處理部分。在C編譯系統編譯源程序之前,先要對源程序中的預處理命令進行處理,處理完畢之後才能對源程序進行編譯。在全屏幕編輯環境下,預處理是在編譯之前自動由系統處理的。 因為大多數程序都用這個printf函數,而這個函數的頭文件是「stdio.h」,所以一般要包括上。
㈨ 預處理指令只能位於C源程序文件的首部嗎 為什麼
不一定的,一般來說是要放在文件的首部的,1、防止編譯時出現,還沒有引入就使用的情況(如一些庫函數等的);2、代碼看起來美觀,大方,便於閱讀和修改