從CSDN看的一些 C艸筆試題 ,希望能幫助愛IT行業(yè)的你!
1:
32 位機上根據(jù)下面的代碼,問哪些說法是正確的? ( )
signed char a = 0xe0;
unsigned int b = a;
unsigned char c = a;
A. a>0 && c>0 為真
B. a == c 為真
C. b 的十六進制表示是:0xffffffe0
D. 上面都不對
解釋:0xe0 十進制為 224 二進制為11100000
char a 為有符號類型,第一位是符號位,0代表正數(shù),1代表負數(shù),所以char a = -32;
而 char c 為 無符號類型,所以a與c肯定不相等, 所以A、B錯誤;
再看C a為char類型占一個字節(jié),b是int類型,占4個字節(jié),把一個字節(jié)賦給4個字節(jié)
缺的應該補符號位,a為 1110000 所以b就是 1111 1111 1111 1111 1111 1111 1110 0000 也就是0xffffffe0;所以選C;
2:
下面哪些選項能編譯通過? ( )
int i;
char a[10];
string f();
string g(string & str);
A. if(!!i){f();}
B. g(f());
C. a=a+1;
D. g("abc");
解釋:
首先排除C,數(shù)組名不能這樣使用,a不能作為左值,因為a是一個常量指針;
再看D,"abc"是 const char * 類型,類型不匹配,所以D錯;
最關鍵的看B選項,string f()返回的是一個臨時變量的對象,而string g(string& str)的參數(shù)是非const引用,C++中有個語法規(guī)則,非const引用不能用臨時變量初始化,C++中這樣使用是為了限制潛在的錯誤。至于原因,網(wǎng)上很多說法沒有一個統(tǒng)一的,但是C++中這樣明確規(guī)定的,我自己感覺g(f());f()返回的這個臨時對象,如果傳給非const引用,有可能被修改,所以不安全,可能引發(fā)很多錯誤。
再看A其實很簡單,是對的
3. int a[10]; 問下面哪些不可以表示 a[1] 的地址? ( )
A. a+sizeof(int)
B. &a[0]+1
C. (int*)&a+1
D. (int*)((char*)&a+sizeof(int))
解釋:
Type* a;
a+ n 的計算規(guī)則
(unsigned int)a + n*sizeof(int)
所以 &a[1]的地址為: (unsigned int)a + 1* sizeof(int);
首先看A,帶入公式為: (unsigned int)a + 4*sizeof(int);錯誤;
再看B,&a[0]就是第一個元素的地址, 帶入公式就是 (unsigned int)a + 1* sizeof(int);正確
再看C,首先這里&a前面為什么加int*,因為&a是數(shù)組的首地址 它的類型是 int(*)[10];而a是數(shù)組首元素的地址,它的類型為int(*); 所以C也正確
再看D 先把&a轉(zhuǎn)化為char* 類型 所以這里相當于: (unsigned int)a + sizeof(int)*sizeof(char);也是正確的;
5:
下面哪些函數(shù)調(diào)用必須進入內(nèi)核才能完成? ( )
A. fopen
B. exit
C. memcpy
D. strlen
解釋:
選AB,fopen打開一個文件,要調(diào)用線程內(nèi)核,exit操作系統(tǒng)才有這個退出的權限,所以也調(diào)用內(nèi)核
CD只是簡單的字符串處理,不需要進入內(nèi)核;
6:
死鎖發(fā)生的必要條件? ( )
A. 互斥條件
B. 請求和保持
C. 不可剝奪
D. 循環(huán)等待
解釋:
選ABCD 不解釋
7:
有兩個線程,最初 n=0,一個線程執(zhí)行 n++; n++; 另一個執(zhí)行 n+=2; 問,最后可能的 n 值? ( )
A. 1
B. 2
C. 3
D. 4
解釋:n++ 與 n+=2 在匯編中有三個過程 第一:讀物n的值;第二:n的值加1或者加2;第三:把n的值寫入內(nèi)存
這三個過程可能被打斷,結(jié)果就是 BCD都有可能。
8. 下面哪些說法正確? ( )
A. 數(shù)組和鏈表都可以隨機訪問
B. 數(shù)組的插入和刪除可以達到 O(1)
C. 哈希表無法法進行范圍檢查
D. 二叉樹無法進行線性訪問
解釋:
A數(shù)組可以隨機訪問,鏈表不可以
B數(shù)組插入要移動很多,不是O(1);
D二叉樹可以先線性化,再進行線性訪問,(這個我也不懂,數(shù)據(jù)結(jié)構(gòu)學的不好)【估計是先遍歷出成數(shù)組,便成了線性訪問?】
C正確
9. 基于比較的排序的時間復雜度下限是多少? ( )
A. O(n)
B. O(n^2)
C. O(nlogn)
D. O(logn)
解釋: 選C 死記硬背
10. 對于下列程序,在一個 big endian 的 32 位的計算機上,b 的結(jié)果是? ( )
unsigned int a = 0x1234;
char b = *((char*)&a);
A. 0x12
B. 0x34
C. 0x00
D. 程序崩潰
解釋:
大端模式:高位存在于低地址。小端模式是高位存在于高地址。
unsigne int a = 0x1234
0x00 0x00 0x12 0x34
低----------------------高
b取低地址第一個地址,所以是 0x00;
11. 編寫函數(shù)求兩個整數(shù) a 和 b 之間的較大值。要求不能使用 if, while, switch, for, ?: 以及任何的比較語句。
int max(int a , int b)
{
int d = a - b;
int flag = (unsigned int )d >> 31; //把符號位移到最低位,欲讓flag為0或1,所以不能補符號位!所以為 unsigned int
int array[] = {a,b};
return array[flag];
}
1. 考慮函數(shù)原型 void hello(int a, int b=7, char* pszC="*"),下面的函數(shù)調(diào)用中屬于不合法調(diào)用的是( )
A. hello(5)
B. hello(5, 8)
C. hello(6, "#")
D. hello(0, 0, "#")
解釋:考C++中參數(shù)的默認變量 選C
2. 一個有 800 個結(jié)點的完全二叉樹,問有多少個葉子結(jié)點? ( )
A. 100
B. 200
C. 400
D. 無法確定
解釋:先求完全二叉樹的深度 h = log2(800) + 1= 9 + 1 = 10;
那么前面9層的節(jié)點數(shù)為 2的9次冪 - 1 為 511;
最后一層節(jié)點數(shù)為 800 - 511 = 289;
289 = 288 + 1 ; 288 所以第九層當中有144個節(jié)點有子節(jié)點;
完全二叉樹第9行也有葉子節(jié)點;
所以第九層有 144+1 = 145個節(jié)點不是葉子節(jié)點;
256- 144 -1 = 111個葉子節(jié)點;
所以有111+289 = 400個葉子節(jié)點;
完全二叉樹特點:
葉子結(jié)點只可能在最大的兩層上出現(xiàn),對任意結(jié)點,若其右分支下的子孫最大層次為L,則其左分支下的子孫的最大層次必為L 或 L+1;
如果一棵具有n個結(jié)點的深度為k的二叉樹,它的每一個結(jié)點都與深度為k的滿二叉樹中編號為1~n的結(jié)點一一對應,這棵二叉樹稱為完全二叉樹。 可以根據(jù)公式進行推導,假設n0是度為0的結(jié)點總數(shù)(即葉子結(jié)點數(shù)),n1是度為1的結(jié)點總數(shù),n2是度為2的結(jié)點總數(shù),由二叉樹的性質(zhì)可知:n0=n2+1,則n= n0+n1+n2(其中n為完全二叉樹的結(jié)點總數(shù)),由上述公式把n2消去得:n= 2n0+n1-1,由于完全二叉樹中度為1的結(jié)點數(shù)只有兩種可能0或1,由此得到n0=(n+1)/2或n0=n/2。 總結(jié)起來,就是 n0=[n/2],其中[]表示上取整。可根據(jù)完全二叉樹的結(jié)點總數(shù)計算出葉子結(jié)點數(shù)。
采用公式 800/2 = 400,選C。
4. 排序算法的穩(wěn)定是指,關鍵碼相同的記錄排序前后相對位置不發(fā)生改變,下面哪種排序算法是不穩(wěn)定的( )
A. 插入排序
B. 冒泡排序
C. 快速排序
D. 歸并排序
解釋: 不穩(wěn)定的:快速排序 希爾排序 堆排序 選擇排序
5. 如下關于進程的描述不正確的是( )
A. 進程在退出時會自動關閉自己打開的所有文件
B. 進程在退出時會自動關閉自己打開的網(wǎng)絡鏈接
C. 進程在退出時會自動銷毀自己創(chuàng)建的所有線程
D. 進程在退出時會自動銷毀自己打開的共享內(nèi)存
解釋:共享內(nèi)存既然是共享的,則可能被幾個進程共同占有,一個進程結(jié)束,如果銷毀了這段共享的內(nèi)存那么其他進程就會招到毀滅;選D
6. 在一個 cpp 文件里面,定義了一個 static 類型的全局變量,下面一個正確的描述是( )
A. 只能在該 cpp 所在的編譯模塊中使用該變量
B. 該變量的值是不可改變的
C. 該變量不能在類的成員函數(shù)中引用
D. 該變量只能是基本類型(如 int, char)不能是 C++類型
解釋:A正確,static具有限制作用域的作用,防止被別的文件引用!D,static可以是類類型;BC明顯錯誤;
7. 下面有關重載函數(shù)的說法中正確的是( )
A. 重載函數(shù)必須具有不同的返回值類型
B. 重載函數(shù)形參個數(shù)必須不同
C. 重載函數(shù)必須有不同的形參列表
D. 重載函數(shù)名可以不同
解釋:C很簡單
9. 下面哪種情況下,B 不能隱式轉(zhuǎn)換為 A ? ( )
A. class B:public A{ };
B. class A:public B{ };
C. class B{ operator A(); };
D. class A{ A(const B&); };
解釋:根據(jù)賦值兼容性原則,子類可以轉(zhuǎn)換為父類賦值給父類對象;但是反過來不正確,所以B錯誤
C中為 類型轉(zhuǎn)換函數(shù),D中為 采用構(gòu)造函數(shù)的方式轉(zhuǎn)換,C和D都可以轉(zhuǎn)換成功!
10. 分析下面程序的運行結(jié)果: ( )
#include
class CBase
{
public:
CBase(){ cout<<"constructing CBase class"<
~CBase(){ cout<<"destructing CBase class"<
};
class CSub : public CBase
{
public:
CSub(){cout<<"constructing CSub class"<
~CSub(){cout<<"destructing CSub class"<
};
void main()
{
CSub obj;
}
A. constructing CSub class
constructing CBase class
destructing CSub class
destructing CBase class
B. constructing CBase class
constructing CSub class
destructing CBase class
destructing CSub class
C. constructing CBase class
constructing CSub class
destructing CSub class
destructing CBase class
D. constructing CSub class
constructing CBase class
destructing CBase class
destructing CSub class
解釋:很簡單 選C
11. 兩個字符串 char* a, char* b,輸出 b 在 a 中的位置次序。
void output_postion(const char* a, const char* b);
如:a = "abdbcc" b = "abc"
b 在 a 中的位置次序為
014
015
034
035
解釋:
#include
#include
#include
using namespace std;
void findCore(string a, int aIndex, string b, int bIndex, list& ans)
{
if(bIndex == b.length())
{
for(list::iterator iter = ans.begin(); iter != ans.end(); iter++)
{
cout<<*iter;
}
cout<
}
else
{
for(int i = aIndex; i < a.length(); i++)
{
if(a[i] == b[bIndex])
{
ans.push_back(i);//如果相等,把序號加入到鏈表l
findCore(a, i + 1 , b , bIndex + 1 , ans);//遞歸
ans.pop_back();//回溯
}
}
}
}
void find(const char* a, const char* b)
{
string as = a;
string bs = b;
list ans;//用來保存 相等的序號
findCore(as , 0 , bs , 0 , ans);
}
int main(int argc, char** argv) {
char* a = "abdbcc";
char* b = "abc";
find(a, b);
return 0;
}