51.h標頭檔案中的ifndef/define/endif 的作用?答:防止該標頭檔案被重複引用。
52.#i nclude 與 #i nclude "file.h"的區別?
答:前者是從standard library的路徑尋找和引用file.h,而後者是從當前工作路徑搜尋並引用file.
h。53.在c++ 程式中呼叫被c 編譯器編譯後的函式,為什麼要加extern 「c」?c++語言支援函式過載,c語言不支援函式過載。c++提供了c連線交換指定符號extern 「c」
解決名字匹配問題。
首先,作為extern是c/c++語言中表明函式和全域性變數作用範圍(可見性)的關鍵字,該關鍵字告訴編譯器,其宣告的函式和變數可以在本模組或其它模組中使用。
通常,在模組的標頭檔案中對本模組提供給其它模組引用的函式和全域性變數以關鍵字extern宣告。例如,如果模組b欲引用該模組a中定義的全域性變數和函式時只需包含模組a的標頭檔案即可。這樣,模組b中呼叫模組a中的函式時,在編譯階段,模組b雖然找不到該函式,但是並不會報錯;它會在連線階段中從模組a編譯生成的目標**中找到此函式
extern "c"是連線申明(linkage declaration),被extern "c"修飾的變數和函式是按照c語言方式編譯和連線的,來看看c++中對類似c的函式是怎樣編譯的:
作為一種物件導向的語言,c++支援函式過載,而過程式語言c則不支援。函式被c++編譯後在符號庫中的名字與c語言的不同。例如,假設某個函式的原型為:
void foo( int x, int y );
該函式被c編譯器編譯後在符號庫中的名字為_foo,而c++編譯器則會產生像_foo_int_int之類的名字(不同的編譯器可能生成的名字不同,但是都採用了相同的機制,生成的新名字稱為「mangled name」)。
_foo_int_int 這樣的名字包含了函式名、函式引數數量及型別資訊,c++就是靠這種機制來實現函式過載的。例如,在c++中,函式void foo( int x, int y )與void foo( int x, float y )編譯生成的符號是不相同的,後者為_foo_int_float。
同樣地,c++中的變數除支援區域性變數外,還支援類成員變數和全域性變數。使用者所編寫程式的類成員變數可能與全域性變數同名,我們以"."來區分。
而本質上,編譯器在進行編譯時,與函式的處理相似,也為類中的變數取了乙個獨一無二的名字,這個名字與使用者程式中同名的全域性變數名字不同。
未加extern "c"宣告時的連線方式
假設在c++中,模組a的標頭檔案如下:
// 模組a標頭檔案 modulea.h
#ifndef module_a_h
#define module_a_h
int foo( int x, int y );
#endif
在模組b中引用該函式:
// 模組b實現檔案 moduleb.cpp
#i nclude "modulea.h"
foo(2,3);
加extern "c"宣告後的編譯和連線方式
加extern "c"宣告後,模組a的標頭檔案變為:
// 模組a標頭檔案 modulea.h
#ifndef module_a_h
#define module_a_h
extern "c" int foo( int x, int y );
#endif
在模組b的實現檔案中仍然呼叫foo( 2,3 ),其結果是:
(1)模組a編譯生成foo的目標**時,沒有對其名字進行特殊處理,採用了c語言的方式;
(2)聯結器在為模組b的目標**尋找foo(2,3)呼叫時,尋找的是未經修改的符號名_foo。
如果在模組a中函式宣告了foo為extern "c"型別,而模組b中包含的是extern int foo( int x, int y ) ,則模組b找不到模組a中的函式;反之亦然。
所以,可以用一句話概括extern 「c」這個宣告的真實目的(任何語言中的任何語法特性的誕生都不是隨意而為的,**於真實世界的需求驅動。我們在思考問題時,不能只停留在這個語言是怎麼做的,還要問一問它為什麼要這麼做,動機是什麼,這樣我們可以更深入地理解許多問題):實現c++與c及其它語言的混合程式設計。
明白了c++中extern "c"的設立動機,我們下面來具體分析extern "c"通常的使用技巧:
extern "c"的慣用法
(1)在c++中引用c語言中的函式和變數,在包含c語言標頭檔案(假設為cexample.h)時,需進行下列處理:
extern "c"
而在c語言的標頭檔案中,對其外部函式只能指定為extern型別,c語言中不支援extern "c"宣告,在.c檔案中包含了extern "c"時會出現編譯語法錯誤。
c++引用c函式例子工程中包含的三個檔案的源**如下:
/* c語言標頭檔案:cexample.h */
#ifndef c_example_h
#define c_example_h
extern int add(int x,int y);
#endif
/* c語言實現檔案:cexample.c */
#i nclude "cexample.h"
int add( int x, int y )
// c++實現檔案,呼叫add:cppfile.cpp
extern "c"
int main(int argc, char* argv)
如果c++呼叫乙個c語言編寫的.dll時,當包括.dll的標頭檔案或宣告介面函式時,應加extern "c" 。
(2)在c中引用c++語言中的函式和變數時,c++的標頭檔案需新增extern "c",但是在c語言中不能直接引用宣告了extern "c"的該標頭檔案,應該僅將c檔案中將c++中定義的extern "c"函式宣告為extern型別。
c引用c++函式例子工程中包含的三個檔案的源**如下:
//c++標頭檔案 cppexample.h
#ifndef cpp_example_h
#define cpp_example_h
extern "c" int add( int x, int y );
#endif
//c++實現檔案 cppexample.cpp
#i nclude "cppexample.h"
int add( int x, int y )
/* c實現檔案 cfile.c
/* 這樣會編譯出錯:#i nclude "cexample.h" */
int main( int argc, char* argv )
15題目的解答請參考《c++中extern 「c」含義深層探索》註解:
幾道c筆試題(含參***)
1. what is displayed when f() is called given the code:
class number
explicit number(short) : type(「short」)
number(int) : type(「int」)
};void show(const number& n)
void f()
a) void
b) short
c) int
d) none of the above
2. which is the correct output for the following code
double darray[2] = , *p, *q;
p = &darray[0];
q = p + 1;
cout << q – p << endl;
cout << (int)q - (int)p << endl;
a) 1 and 8
b) 8 and 4
c) 4 and 8
d) 8 and 1
第乙個選c;
雖然傳入的是short型別,但是short型別的建構函式被生命被explicit,也就是只能顯示型別轉換,不能使用隱式型別轉換。
第二個選a;
第乙個是指標加減,按照的是指向位址型別的加減,只跟型別位置有關,q和p指向的資料型別以實際資料型別來算差乙個位置,因此是1。而第二個加減是實際指標值得加減,在記憶體中乙個double型別佔據8個位元組,因此是8
54.sony筆試題
1.完成下列程式
**.*.
#include
#define n 8
int main()
2.完成程式,實現對陣列的降序排序
#include
void sort( );
int main()
; //數字任//意給出
sort( );
return 0;
}void sort( )
3.費波那其數列,1,1,2,3,5……編寫程式求第十項。可以用遞迴,也可以用其
他方法,但要說明你選擇的理由。
#include
int pheponatch(int);
int main()
int pheponatch(int n)
4.下列程式執行時會崩潰,請找出錯誤並改正,並且說明原因。
#include
#include
typedef struct tnode;
tnode* root=null;
void append(int n);
int main()
void append(int n)
else
if(n>=temp.value)
temp.left=newnode;
else
temp.right=newnode;
return;
}}※ **:·哈工大紫丁香
mengfd (icebreaker) 於 (sun oct 23 14:59:59 2005) 說道:
55請你分別畫出osi的七層網路結構圖和tcp/ip的五層結構圖。應用層:為應用程式提供服務
表示層:處理在兩個通訊系統中交換資訊的表示方式
會話層:負責維護兩個結點間會話連線的建立、管理和終止,以及資料交換
傳輸層:向使用者提供可靠的端到端服務。udp tcp協議。
網路層:通過路由選擇演算法為分組通過通訊子網選擇最適當的路徑,以及實現擁塞控制、網路互聯等功能。資料傳輸單元是分組。ip位址,路由器,ip協議。
資料鏈路層:在物理層提供的服務基礎上,資料鏈路層在通訊的實體間建立資料鏈路連線,傳輸一幀為單位的資料報(,並採用差錯控制與流量控制方法,使有差錯的物理線路變成無差錯的資料鏈路。)
物理層:傳輸位元流。傳輸單元是位元。數據機。
56請你詳細地解釋一下ip協議的定義,在哪個層上面?主要有什麼作用?tcp與udp呢 ?網路層。
57.請問交換機和路由器各自的實現原理是什麼?分別在哪個層次上面實現的?交換機:資料鏈路層。路由器:網路層。
58.全域性變數和區域性變數有什麼區別?是怎麼實現的?作業系統和編譯器是怎麼知道的 ?
59.8086是多少位的系統?在資料匯流排上是怎麼實現的?
8086微處理器共有4個16位的段暫存器,在定址記憶體單元時,用它們直接或間接地存放段位址。
**段暫存器cs:存放當前執行的程式的段位址。
資料段暫存器ds:存放當前執行的程式所用運算元的段位址。
堆疊段暫存器ss:存放當前執行的程式所用堆疊的段位址。
附加段暫存器es:存放當前執行程式中乙個輔助資料段的段位址。
由cs:ip構成指令位址,ss:sp構成堆疊的棧頂位址指標。ds和es用作資料段和附加段的段位址(段起始位址或段值)
8086/8088微處理器的儲存器管理
1.位址線(碼)與定址範圍:n條位址線定址範圍=2n
2.8086有20位址線定址範圍為1mb由 00000h~fffffh
3. 8086微處理器是乙個16位結構,使用者可用的暫存器均為16位:定址64kb
4. 8086/8088採用分段的方法對儲存器進行管理。具體做法是:
把1mb的儲存器空間分成若干段,每段容量為64kb,每段儲存器的起始位址必須是乙個能被16整除的位址碼,即在20位的二進位制位址碼中最低4位必須是「0」。每個段首位址的高16位二進位制**就是該段的段號(稱段基位址)或簡稱段位址,段號儲存在段暫存器中。我們可對段暫存器設定不同的值來使微處理器的儲存器訪問指向不同的段。
5.段內的某個儲存單元相對於該段段首位址的差值,稱為段內偏移位址(也叫偏移量)用16位二進位制**表示。
6.實體地址是由8086/8088晶元位址引線送出的20位位址碼,它用來參加儲存器的位址解碼,最終讀/寫所訪問的乙個特定的儲存單元。
7.邏輯位址由某段的段位址和段內偏移位址(也叫偏移量)兩部分所組成。寫成:
8.在硬體上起作用的是實體地址,實體地址=段基位址×10h十偏移位址
聯想筆試題
1.設計函式 int atoi(char *s)。
2.int i=(j=4,k=8,l=16,m=32); printf(「%d」, i); 輸出是多少?
C 面試題 C 基礎程式設計題
case 8 cout auguest break case 9 cout september break case 10 cout october break case 11 cout november break case 12 cout december break cout 29.22.程式...
常見C 面試程式設計題題經典分析
1.引言 許多面試題看似簡單,卻需要深厚的基本功才能給出完美的解答。企業要求面試者寫乙個最簡單的strcpy函式都可看出面試者在技術上究竟達到了怎樣的程度,我們能真正寫好乙個strcpy函式嗎?我們都覺得自己能,可是我們寫出的strcpy很可能只能拿到10分中的2分。讀者可從本文看到strcpy 函...
C語言面試演算法題 二
1.寫乙個函式,它的原形是int continumax char outputstr,char intputstr 功能 在字串中找出連續最長的數字串,並把這個串的長度返回,並把這個最長數字串付給其中乙個函式引數outputstr所指記憶體。例如 abcd12345ed125ss123456789 ...