46) 位域 :
有些資訊在儲存時,並不需要占用乙個完整的位元組, 而只需佔幾個或乙個二進位制位。例如在存放乙個開關量時,只有0和1 兩種狀態,用一位二進位即可。為了節省儲存空間,並使處理簡便,c語言又提供了一種資料結構,稱為「位域」或「位段」。
所謂「位域」是把乙個位元組中的二進位劃分為幾個不同的區域,並說明每個區域的位數。每個域有乙個網域名稱,允許在程式中按網域名稱進行操作。這樣就可以把幾個不同的物件用乙個位元組的二進位制位域來表示。
一、位域的定義和位域變數的說明位域定義與結構定義相仿,其形式為:
struct 位域結構名 ; 其中位域列表的形式為:型別說明符位網域名稱:位域長度
例如:struct bs
; 位域變數的說明與結構變數說明的方式相同。可採用先定義後說明,同時定義說明或者直接說明這三種方式。例如:
struct bs
data;
說明data為bs變數,共佔兩個位元組。其中位域a佔8位,位域b佔2位,位域c佔6位。對於位域的定義尚有以下幾點說明:
乙個位域必須儲存在同乙個位元組中,不能跨兩個位元組。如乙個位元組所剩空間不夠存放另一位域時,應從下一單元起存放該位域。也可以有意使某位域從下一單元開始。例如:
struct bs
在這個位域定義中,a佔第一位元組的4位,後4位填0表示不使用,b從第二位元組開始,占用4位,c占用4位。
由於位域不允許跨兩個位元組,因此位域的長度不能大於乙個位元組的長度,也就是說不能超過8位二進位。
位域可以無位網域名稱,這時它只用來作填充或調整位置。無名的位域是不能使用的。例如:
struct k
; 從以上分析可以看出,位域在本質上就是一種結構型別,不過其成員是按二進位分配的。
位域的使用位域的使用和結構成員的使用相同,其一般形式為:位域變數名?位網域名稱位域允許用各種格式輸出。
main()
bit,*pbit;
bit.a=1;
bit.b=7;
bit.c=15;
pri47) 改錯:
#include
int main(void)
解答:搞錯了,是指標型別不同,int **p; //二級指標&arr; //得到的是指向第一維為100的陣列的指標
#include
int main(void)
48) 下面這個程式執行後會有什麼錯誤或者效果:
#define max 255
int main()
解答:死迴圈加陣列越界訪問(c/c++不進行陣列越界檢查)max=255 陣列a的下標範圍為:0..max-1,這是其一..
其二.當i迴圈到255時,迴圈內執行:a[255]=255;這句本身沒有問題..
但是返回for (i=0;i<=max;i++)語句時,由於unsigned char的取值範圍在(0..255),i++以後i又為0了..無限迴圈下去。
49) struct name1
struct name2
sizeof(struct name1)=8,sizeof(struct name2)=12
在第二個結構中,為保證num按四個位元組對齊,char後必須留出3位元組的空間;同時為保證整個結構的自然對齊(這裡是4位元組對齊),在x後還要補齊2個位元組,這樣就是12位元組。
50) intel:
a.c 和b.c兩個c檔案中使用了兩個相同名字的static變數,編譯的時候會不會有問題?這兩個static變數會儲存到**(棧還是堆或者其他的)?
static的全域性變數,表明這個變數僅在本模組中有意義,不會影響其他模組。他們都放在資料區,但是編譯器對他們的命名是不同的。如果要使變數在其他模組也有意義的話,需要使用extern關鍵字。
51) struct s1
; struct s2
; printf("sizeof(s1)= %d\n", sizeof(s1));
printf("sizeof(s2)= %d\n", sizeof(s2));
result: 16, 24
第乙個struct s1
; 理論上是這樣的,首先是i在相對0的位置,佔8位乙個位元組,然後,j就在相對乙個位元組的位置,由於乙個位置的位元組數是4位的倍數,因此不用對齊,就放在那裡了,然後是a,要在3位的倍數關係的位置上,因此要移一位,在15位的位置上放下,目前總共是18位,折算過來是2位元組2位的樣子,由於 double 是8位元組的,因此要在相對0要是8個位元組的位置上放下,因此從18位開始到8個位元組之間的位置被忽略,直接放在8位元組的位置了,因此,總共是16位元組。
第二個最後會對照是不是結構體內最大資料的倍數,不是的話,會補成是最大資料的倍數。
40. 鍊錶題:乙個鍊錶的結點結構
struct node
;typedef struct node node ;
(1)已知鍊錶的頭結點head,寫乙個函式把這個鍊錶逆序 ( intel)
node * reverselist(node *head) //鍊錶逆序
p2->next = p1 ;
head = p2 ;
return head ;
}(2)已知兩個鍊錶head1 和head2 各自有序,請把它們合併成乙個鍊錶依然有序。(保留所有結點,即便大小相同)
node * merge(node *head1 , node *head2)
else
node *pcurrent = head ;
while ( p1 != null && p2 != null)
else
}if ( p1 != null )
pcurrent->next = p1 ;
if ( p2 != null )
pcurrent->next = p2 ;
return head ;
}(3)已知兩個鍊錶head1 和head2 各自有序,請把它們合併成乙個鍊錶依然有序,這次要求用遞迴方法進行。 (autodesk)
答案:node * mergerecursive(node *head1 , node *head2)
else
return head ;
}41. 分析一下這段程式的輸出 (autodesk)
class b
~b()
b(int i):data(i) //b(int) works as a converter ( int -> instance of b)
private:
int data;
};b play( b b)
(1) results:
int main(int argc, char* argv) constructed by parameter 5
destructed t1
(2) results:
int main(int argc, char* argv) constructed by parameter 5
destructed t2 注意順序!
destructed t1
42. 寫乙個函式找出乙個整數陣列中,第二大的數 (microsoft)
答案:const int minnumber = -32767 ;
int find_sec_max( int data , int count)
else
}return sec_max ;
}43. 寫乙個在乙個字串(n)中尋找乙個子串(m)第乙個位置的函式。
kmp演算法效率最好,時間複雜度是o(n+m)。
44. 多重繼承的記憶體分配問題:
比如有class a : public class b, public class c {}
那麼a的記憶體結構大致是怎麼樣的?
這個是compiler-dependent的, 不同的實現其細節可能不同。
如果不考慮有虛函式、虛繼承的話就相當簡單;否則的話,相當複雜。
45. 如何判斷乙個單鏈表是有環的?(注意不能用標誌位,最多只能用兩個額外指標)
struct node
bool check(const node* head) {} //return false : 無環;true: 有環
一種o(n)的辦法就是(搞兩個指標,乙個每次遞增一步,乙個每次遞增兩步,如果有環的話兩者必然重合,反之亦然):
bool check(const node* head)
return false;}
C 經典面試題
本試題僅用於考查c c程式設計師的基本程式設計技能。內容限於c c常用語法,不涉及資料結構 演算法以及深奧的語法。考試成績能反映出考生的程式設計質量以及對c c的理解程度,但不能反映考生的智力和軟體開發能力。筆試時間90分鐘。請考生認真答題,切勿輕視。一 請填寫bool float,指標變數與 零值...
經典C面試題
1.找錯題 void test1 string只能容納9個字元,複製的時候會越界 2.找錯題 void test2 strcpy string,str1 由於在陣列str1內沒有 n 所以複製的長度不確定,導致string結束不確定。3 找錯題 void test3 char str1 strlen...
C經典面試題
1.gets 函式 問 請找出下面 裡的問題 1.include 2.int main void 3.答 上面 裡的問題在於函式gets 的使用,這個函式從stdin接收乙個字串而不檢查它所複製的快取的容積,這可能會導致快取溢位。這裡推薦使用標準函式fgets 代替。2.strcpy 函式 問 下面...