以預編譯頭文件為Stdafx.h為例:
Qt Creator中很簡單,只需在.pro文件中加入一行PRECOMPILED_HEADER = stdafx.h
VS2008在工程中在Stdafx.h文件上右鍵propertis-Configuration Properties-C/C++-Precompiled Headers-Create/Use Precompiled Header中選擇Create Precompiled Header(/y).
有一點注意的是,在工程Generated Filed中的moc相關文件也需要選上Use Precompiled Header (/Yu).
2. 求C語言中預編譯命令表
1 宏定義即是字元串替換。宏分為無參宏和含參宏。定義宏的位置可以在函數外部也可以在函數內部(vc++ 2008 測試通過)。宏的作用域是從定義處到取消定義命令[#undef 宏名]之間的部分,若無顯式的#undef命令則默認到文件結束。可以使用defined命令可以判斷宏是否被定義#if defined X (=#ifdef X),#if !defined X (= ifndef X)。 定義含參宏格式如#define SQ(y) ((y)*(y)),其中參數為y,宏得到的是y平方。為了保證宏替換的正確性,多加了3個括弧。但這樣的保證也是有限的,它要求y的值不能在(y)內改變,如把y換成i++將得不到期望的結果。 宏調用(實際上是宏替換)不用考慮形參的類型,這帶來一定的好處。如求兩個數最大值的宏#define MAX(a,b) (a>b)?a:b,實參可以是int,double等。宏定義可以包括多個語句,如#define CHANGE(X1,X2,X3,X4) X1 += 1;X2 += 2; X3 += 3; X4 +=4; 2 文件包含命令#include的功能是把指定的文件插入該命令行位置取代該命令行,從而把指定的文件和當前的源程序文件連成一個源文件。 源代碼分布於多個文件時,建議使用調用文件+頭文件+實現文件的模式。頭文件中包含要用到的函數說明,類型定義,宏定義,常數值等。具體的實現放在實現文件中。在調用文件和實現文件中都包含該頭文件即可。為了避免重復包含頭文件,可在頭文件中使用#ifndef [頭文件標示符(如X_Header等等)] + 頭文件內容 + #endif模式。 3 條件編譯命令可以按不同的條件去編譯不同的程序部分,因而產生不同的目標代碼文件。 這對於程序的移植和調試很有用。條件編譯有三種形式,下面分別介紹:
第一種形式根據有無對應宏定義選擇編譯程序段:
#ifdef 標識符 // 或 #ifndef 標示符
程序段1
#else
程序段2
#endif 第二種形式根據常量表達式值選擇編譯,值為非0執行if段。#if 常量表達式
程序段1
#else
程序段2
#endif
這里一定要是常量表達式,一般為宏。若是表達式包含變數則編譯器只能隨便猜一個了。 第三種形式含有#elif,看個例子吧#define ABC 3
void main(){#if ABC>0
int a=1;
printf("%d/n",a);
#elif ABC<0
int b=-1;
printf("%d/n",b);
#else
int c=0;
printf("%d/n",c);
#endif
} 其餘的預編譯命令如下,這里就不研究它們了。#line 標志該語句所在的行號
# 將宏參數替代為以參數值為內容的字元竄常量
## 將兩個相鄰的標記(token)連接為一個單獨的標記
#pragma 說明編譯器信息#warning 顯示編譯警告信息
#error 顯示編譯錯誤信息
3. C語言預編譯命令
<>裡面為庫文件名
stdio為基本輸入輸出庫,
string為字元串操作庫
詳細的可以看這個:
http://..com/question/257653832.html
4. c語言編譯預處理
編譯,編譯程序讀取源程序(字元流),對之進行詞法和語法的分析,將高級語言指令轉換為功能等效的匯編代碼,再由匯編程序轉換為機器語言,並且按照操作系統對可執行文件格式的要求鏈接生成可執行程序。
如果用一張圖來表示:
讀取c源程序,對其中的偽指令(以#開頭的指令)和特殊符號進行處理
[析] 偽指令主要包括以下四個方面
(1)宏定義指令,如#define Name TokenString,#undef等。對於前一個偽指令,預編譯所要做的是將程序中的所有Name用TokenString替換,但作為字元串常量的Name則不被替換。對於後者,則將取消對某個宏的定義,使以後該串的'出現不再被替換。
(2)條件編譯指令,如#ifdef,#ifndef,#else,#elif,#endif,等等。這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據有關的文件,將那些不必要的代碼過濾掉
(3)頭文件包含指令,如#include "FileName"或者#include 等。在頭文件中一般用偽指令#define定義了大量的宏(最常見的是字元常量),同時包含有各種外部符號的聲明。採用頭文件的目的主要是為了使某些定義可以供多個不同的C源程序使用。因為在需要用到這些定義的C源程序中,只需加上一條#include語句即可,而不必再在此文件中將這些定義重復一遍。預編譯程序將把頭文件中的定義統統都加入到它所產生的輸出文件中,以供編譯程序對之進行處理。
包含到c源程序中的頭文件可以是系統提供的,這些頭文件一般被放在/usr/include目錄下。在程序中#include它們要使用尖括弧(<>)。另外開發人員也可以定義自己的頭文件,這些文件一般與c源程序放在同一目錄下,此時在#include中要用雙引號("")。
(4)特殊符號,預編譯程序可以識別一些特殊的符號。例如在源程序中出現的LINE標識將被解釋為當前行號(十進制數),FILE則被解釋為當前被編譯的C源程序的名稱。預編譯程序對於在源程序中出現的這些串將用合適的值進行替換。
注意:
預編譯程序所完成的基本上是對源程序的「替代」工作。經過此種替代,生成一個沒有宏定義、沒有條件編譯指令、沒有特殊符號的輸出文件。這個文件的含義同沒有經過預處理的源文件是相同的,但內容有所不同。下一步,此輸出文件將作為編譯程序的輸出而被翻譯成為機器指令。
5. 問題:1.C語言程序能有多少個main()函數2.一個C文件能有多少個main函數 3.main()能放在#指令前嗎
1.
c語言程序只能有一個main函數,因為main函數是整個進程的入口
2.
一個c文件可以有1或者0個main,但是一卜碰橘個c程序只能有1個main
3.
帶#的這些型團都屬於吵巧預編譯指令,你可以放在任意位置,但是由於編譯器是從上到下順序編譯的,加入你定義了一個宏#define在main函數里有使用,而宏卻在main函數之後,所以預編譯的時候main函數內的相關部分宏不會被替換,所以對於預編譯指令最好放在文件的開頭
純手打,望採納
6. 什麼是預編譯,何時需要預編譯
預編譯又稱為預處理,是做些代碼文本的替換工作
預編譯又稱為預處理,是做些代碼文本的替換工作
處理#開頭的指令,比如拷貝#include包含的文件代碼,#define宏定義的替換,條件編譯等
就是為編譯做的預備工作的階段
主要處理#開始的預編譯指令
預編譯指令指示了在程序正式編譯前就由編譯器進行的操作,可以放在程序中的任何位置。常見的預編譯指令有:
(1)#include 指令
該指令指示編譯器將xxx.xxx文件的全部內容插入此處。若用<>括起文件則在系統的INCLUDE目錄中尋找文件,若用" "括起文件則在當前目錄中尋找文件。一般來說,該文件是後綴名為"h"或"cpp"的頭文件。
注意:<>不會在當前目錄下搜索頭文件,如果我們不用<>而用""把頭文件名擴起,其意義為在先在當前目錄下搜索頭文件,再在系統默認目錄下搜索。
(2)#define指令
該指令有三種用法:
第一種是定義標識,標識有效范圍為整個程序,形如#define XXX,常與#if配合使用;
第二種是定義常數,如#define max 100,則max代表100(這種情況下使用const定義常數更好,原因見注1);
第三種是定義"函數",如#define get_max(a, b) ((a)>(b)?(a):(b)) 則以後使用get_max(x,y)就可以得到x和y中較大的數(這種方法存在一些弊病,見注2)。
第四種是定義"宏函數",如#define GEN_FUN(type) type max_##type(type a,type b){return a>b?a:b;} ,使用時,用GEN_FUN(int),則此處預編譯後就變成了 max_int(int a,int b){return a>b?a:b;},以後就可以使用max_int(x,y)就可以得到x和y中較大的數.比第三種,增加了類型的說明。
(3)#if、#else和#endif指令
這些指令一般這樣配合使用:
#if defined(標識) //如果定義了標識
要執行的指令
#else
要執行的指令
#endif
在頭文件中為了避免重復調用(比如說兩個頭文件互相包含對方),常採用這樣的結構:
#if !(defined XXX) //XXX為一個在你的程序中唯一的標識符,
//每個頭文件的標識符都不應相同。
//起標識符的常見方法是若頭文件名為"abc.h"
//則標識為"abc_h"
#define XXX
真正的內容,如函數聲明之類
#endif
7. C語言預編譯命令#include<myfile.h>與#include"myfile.h"的功能
正確。
在用法上,只是查找文件路徑的順序不同,<>包含,會默認優先查找系統文件,然後是工程文件和當前目錄下文件,而""包含,會默認優先查找當前工程和目錄下文件,這對於自定義頭文件是沒有區別的。
8. 預編譯命令行由什麼符號開頭
#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
9. 預編譯命令都有哪些
一、預編譯命令具體什麼意思?哪鋒
答:預編譯命令是由ANSI C統一規定的,但是它不是C語言的組成部分冊清,不能直接對它們進行編譯。必須在對程序進行通常的編(包括詞法和語法分析,代碼生成,優化等)之前,先對程序中這些特殊的命令進行「預處理」,你慢慢悟,我小學生文化都看懂皮毛了,我不信你不知道它的意思。
二、#include <stdio.h>什麼意思?
答:把stdio.h這個文件包含進來,至於stdio.h是什麼,你自己慢慢看。
三、 void main()這個是什麼意思??
答:加州緩前void 表示無類型,
我們知道main()是系統調用的,
那麼在main()前面加 void就保證系統不使用main()函數帶回的任何值。
10. MFC源代碼是如何鏈接到程序中的
1. 預處理
預處理相當於根據預處理指令組裝新的C/C++程序。經過預處理,會產生一個沒有宏定義,沒有條件編譯指令,沒有特殊符號的輸出文件,這個文件的含義同原本的文件無異,只是內容上有所不同。
讀取C/C++源程序,對其中的偽指令(以#開頭的指令)進行處理
①將所有的「#define」刪除,並且展開所有的宏定義
②處理所有的條件編譯指令,如:「#if」、「#ifdef」、「#elif」、「#else」、「endif」等。這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序對哪些代碼進行處理。預編譯程序將根據有關的文件,將那些不必要的代碼過濾掉。
③處理「#include」預編譯指令,將被包含的文件插入到該預編譯指令的位置。
(注意:這個過程可能是遞歸進行的,也就是說被包含的文件可能還包含其他文件)
刪除所有的注釋
添加行號和文件名標識。
以便於編譯時編譯器產生調試用的行號信息及用於編譯時產生的編譯錯誤或警告時能夠顯示行號
保留所有的#pragma編譯器指令
2. 編譯
將預處理完的文件進行一系列詞法分析、語法分析、語義分析及優化後,產生相應的匯編代碼文件。
3. 匯編
將編譯完的匯編代碼文件翻譯成機器指令,並生成可重定位目標程序的.o文件,該文件為二進制文件,位元組編碼是機器指令。
匯編器是將匯編代碼轉變成機器可以執行的指令,每一個匯編語句幾乎都對應一條機器指令。所以匯編器的匯編過程相對於編譯器來講比較簡單,它沒有復雜的語法,也沒有語義,也不需要做指令優化,只是根據匯編指令和機器指令的對照表一一翻譯即可。
4. 鏈接
通過鏈接器將一個個目標文件(或許還會有庫文件)鏈接在一起生成一個完整的可執行程序。
由匯編程序生成的目標文件並不能立即就被執行,其中可能還有許多沒有解決的問題。
例如,某個源文件中的函數可能引用了另一個源文件中定義的某個符號(如變數或者函數調用等);在程序中可能調用了某個庫文件中的函數,等等。所有的這些問題,都需要經鏈接程序的處理方能得以解決。
鏈接程序的主要工作就是將有關的目標文件彼此相連接,也就是將在一個文件中引用的符號同該符號在另外一個文件中的定義連接起來,使得所有的這些目標文件成為一個能夠被操作系統裝入執行的統一整體。
至此,大致經過這幾個步驟,一個完整的可執行程序產生了。