當(dāng)前位置:
首頁 >
部分真题整理2
發(fā)布時(shí)間:2025/10/17
21
豆豆
1、聲明一個(gè)指向含有10個(gè)元素的數(shù)組的指針,其中每個(gè)元素是一個(gè)函數(shù)指針,該函數(shù)的返回值是int,參數(shù)是int*,正確的是(C)
(int *p[10])(int*) int [10]*p(int *) int (*(*p)[10])(int *) int ((int *)[10])*p以上選項(xiàng)都不正確
解析:
int (*(*func)[5])(int *p);
func被一個(gè)圓括號包含,左邊又有一個(gè)*,那么func是一個(gè)指針,跳出括號,右邊是一個(gè)[]運(yùn)算符號,說明func是一個(gè)指向數(shù)組的指針,現(xiàn)在往左看,左邊有一個(gè)*號,說明這個(gè)數(shù)組的元素是指針,再跳出括號,右邊又有一個(gè)括號,說明這個(gè)數(shù)組的元素是指向函數(shù)的指針。總結(jié)一下,就是:func是一個(gè)指向數(shù)組的指針,這個(gè)數(shù)組的元素是函數(shù)指針,這些指針指向具有int*形參,返回值為int類型的函數(shù)。
詳見:http://blog.csdn.net/u011385799/article/details/47783555
2、 一個(gè)進(jìn)程從執(zhí)行狀態(tài)轉(zhuǎn)換到阻塞狀態(tài)的可能原因是本進(jìn)程(BD)。
時(shí)間片完
需要等待其他進(jìn)程的執(zhí)行結(jié)果
執(zhí)行了V操作
執(zhí)行了P操作
解析:
運(yùn)行態(tài):進(jìn)程占用CPU,并在CPU上運(yùn)行;
就緒態(tài):進(jìn)程已經(jīng)具備運(yùn)行條件,但是CPU還沒有分配過來;
阻塞態(tài):進(jìn)程因等待某件事發(fā)生而暫時(shí)不能運(yùn)行; 進(jìn)程在一生中,都處于上述3中狀態(tài)之一。
運(yùn)行---》就緒: 時(shí)間片用完。
就緒---》運(yùn)行:運(yùn)行的進(jìn)程的時(shí)間片用完,調(diào)度就轉(zhuǎn)到就緒隊(duì)列中選擇合適的進(jìn)程分配CPU
運(yùn)行---》阻塞:發(fā)生了I/O請求或等待某件事的發(fā)生
阻塞---》就緒:進(jìn)程所等待的事件發(fā)生,就進(jìn)入就緒隊(duì)列
P操作是阻塞作用
V操作是喚醒作用
13
15
26
(1)b=a*2,c=a+11,a=c,a=b a=4
(2)b=a*2,c=a+11,a=b,a=c a=13
(3)b=a*2,a=b,c=a+11,a=c a=15
(4)c=a+11,a=c,b=a*2,a=b a=26
4、以下程序段的輸出結(jié)果是(A)
char s[]="\\123456\123456\t"; printf("%d\n",strlen(s));12
13
16
以上都不對
解析:
char s[] = "//123456/123456/t";
這樣strlen(s)輸出17.
char s[] = "\\123456\123456\t";
這樣strlen(s)輸出12.
計(jì)算字符串長度時(shí)關(guān)鍵是要注意辨認(rèn)轉(zhuǎn)義字符;
含轉(zhuǎn)義字符的有:
\\ 表示字符 \
\123表示字符 {
\t 表示制表符
這些都是一個(gè)字符。
5、如下程序
#include <iostream> using namespace std;class A { public: A() { printf("A"); } };int main() { A *p1 = new A; A *p2 = (A *)malloc(sizeof(A));return 0; }該程序運(yùn)行結(jié)果為(A)
A
AA
崩潰
不可預(yù)測
解析:
1 A *p1 = new A;
上面這條語句會(huì)創(chuàng)建一個(gè)A對象,輸出一個(gè)A;
1 A *p2 = (A *)malloc(sizeof(A));
sozeof(A)為1,這條語句創(chuàng)建一個(gè)大小為1的A的指針數(shù)組,但是沒有創(chuàng)建任何A對象,因此不輸出A
這題主要是考的new和malloc的區(qū)別,new會(huì)分配內(nèi)存,并調(diào)用類的構(gòu)造函數(shù)創(chuàng)建對象,而malloc只是分配內(nèi)存,不調(diào)用類的構(gòu)造函數(shù)創(chuàng)建對象,這個(gè)程序應(yīng)該用delete p1;顯示釋放掉p1所指的堆上的內(nèi)存,這樣才會(huì)調(diào)用類的析構(gòu)函數(shù),否則不會(huì)調(diào)用。
6、設(shè)有以下宏定義:
#define N 3 #define Y(n)((N+1)*n)則執(zhí)行語句:z=2*(N+Y(5+1));后,z的值為:(C)
38
42
48
54
解析:
#define N 3
#define Y(n)((N+1)*n)//【注意此處n沒有加括號】,所以后面的n并不是(5+1)
z=2*(N+Y(5+1)) =2*(N+(N+1)*5+1)=2*(3+4*5+1)=48
7、 以下描述正確的是?(C)
虛函數(shù)是可以內(nèi)聯(lián)的,可以減少函數(shù)調(diào)用的開銷提高效率
類里面可以同時(shí)存在函數(shù)名和參數(shù)都一樣的虛函數(shù)和靜態(tài)函數(shù)
父類的析構(gòu)函數(shù)是非虛的,但是子類的析構(gòu)函數(shù)是虛的,delete子類對象指針會(huì)調(diào)用父類的析構(gòu)函數(shù)
以上都不對
解析:
delete子類對象是一定會(huì)調(diào)用父類的析構(gòu)函數(shù)的先調(diào)用子類的析構(gòu)函數(shù)然后調(diào)用父類的析構(gòu)函數(shù);如果要調(diào)用父類指向子類的對象,此時(shí)才需要父類的析構(gòu)函數(shù)是虛的。
8、下列運(yùn)算符中,在C++語言中不能重載的是:(C)
*
>=
::
delete
解析:
在C++中,sizeof運(yùn)算符,.成員運(yùn)算符,.*成員指針運(yùn)算符,::作用域解析運(yùn)算符以及?:條件運(yùn)算符不能被重載
9、說明一下++p 與 p++ 的區(qū)別。(B)
沒有區(qū)別
++p更好一些
p++更好一些
和編譯器有關(guān)
解析:
假設(shè)這樣的一個(gè)例子:
int p = -1; int y = 0; y = p++ + ++P;先分析一下它的匯編代碼(沒有優(yōu)化):
subl $40, %esp ; 分配40字節(jié) movl $1, -16(%ebp) ; 存儲(chǔ) p movl $0, -12(%ebp) ; 存儲(chǔ) y movl -16(%ebp), %eax ; 這3步執(zhí)行 p++ leal 1(%eax), %edx movl %edx, -16(%ebp) addl $1, -16(%ebp) ; 這2步執(zhí)行 ++p movl -16(%ebp), %edx addl %eax, %edx ; 相加操作 movl %edx, -12(%ebp) ; 結(jié)果寫回 y 可以看出p++需要3步,++p需要2步,而且修改p的值是不一樣的,看出++p的效率比p++的高。
前++返回對象的引用,效率較高,故選擇++p
10、下面有關(guān)final, finally, finalize的區(qū)別描述錯(cuò)誤的是?(B)
如果一個(gè)類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承
如果一個(gè)方法被聲明為final,可以被覆蓋
finally在異常處理時(shí)提供 finally 塊來執(zhí)行任何清除操作。
Java使用 finalize() 方法在垃圾收集器象從內(nèi)存中清除出去之前做必要的清理工作
解析:
final關(guān)鍵字可用于修飾類、變量和方法。final修飾的類不能被繼承,final修飾的方法不能被重寫,final修飾的變量不可被修改,一旦獲得初始值,該變量就不能被重新賦值。
11、 以下選項(xiàng)中函數(shù)形參不是指針的是?(C)
fun( int ﹡a ){…}
fun( int a [ 10 ] ) {…}
fun( int &p ) {…}
fun( int p[ ]) {…}
解析:
B選項(xiàng)和D選項(xiàng)是將數(shù)組作為函數(shù)參數(shù);A選項(xiàng)是將指針作為函數(shù)參數(shù);
C. 這個(gè)& 是引用,不是取地址.
12、下面程序應(yīng)該輸出多少?(A)
char *c[] = { "ENTER", "NEW", "POINT", "FIRST" }; char **cp[] = { c+3, c+2, c+1, c }; char ***cpp = cp; int main(void) { printf("%s", **++cpp); printf("%s", *--*++cpp+3); printf("%s", *cpp[-2]+3); printf("%s\n", cpp[-1][-1]+1); return 0; }POINTERSTEW
FERSTEPOINW
NEWPOINTW
POINTFIREST
解析:
這個(gè)主要是執(zhí)行順序的問題,我加了一下括號:
printf("%s\n", **(++cpp));
printf("%s\n", (*(--(*(++cpp)))) + 3);
printf("%s\n", *(cpp[-2]) + 3);
printf("%s\n", cpp[-1][-1] + 1);
其中考了指針應(yīng)用,隱含中也考了運(yùn)算符優(yōu)先級的問題(*--*++cpp+3)
c是一個(gè)指針數(shù)組,每個(gè)數(shù)組單元都是一個(gè)指針,指向一個(gè)字符創(chuàng)。
即c[0]="ENTER"......c[3]="FIRST"
由于[]與*運(yùn)算本質(zhì)幾乎是一致的,以下用[]替換*更容易理解。
c[i]=*(c+i)
c和c+i都是char*[]類型,它可以退化成char**類型,它正好是一個(gè)char**數(shù)組
cp[0]=c+3 .....cp[3]=c
引用后cp[0][0]=*(c+3)=c[3]="FIRST"
cp是char**[]類型,它可以退化成char***類型,正好與cpp類型一致。
1>++ccp的值是cp+1 *++p=*(cp+1)=cp[1] **++p=*(cp[1])=c[2]="POINT"
2>運(yùn)算符優(yōu)先級決定運(yùn)算先后關(guān)系
++ccp的值是cp+2 *++p=*(cp+2)=cp[2]=c+1 --*++p=c *--*++p=*(c+0)=c[0]="ENTER"再+3字符串指向"ER"
3>cpp的值為cp+2 cpp[-2]=*(cpp-2)=*(cp+2-2)=cp[0]=c+3再引用*(c+3)=c[3]="FIRST"字符串指到"ST"
4>cpp的值沒變,cpp[-1]=*(cpp-1)=*(cp+2-1)=cp[1]=c+2再[-1]得*(c+2-1)=c[1]="NEW",+1字符創(chuàng)指針指到"EW"
翻來覆去,記得這個(gè)換算關(guān)系式即可,c[i]=*(c+i)。
13、 有如下程序段:
void GetMemeory(char* p) { p = (char*) malloc (100); } void test() { char *str=NULL; GetMemory(str); strcpy(str,”Thunder”); strcat(str+2, “Downloader”);//*(str+2)=u;把Downloader連接到str+2的串尾后 printf(str); }請問運(yùn)行Test函數(shù)結(jié)果是:(D)
Thunder Downloader
under Downloader
Thunderownloader
程序崩潰
解析:
在函數(shù)中給指針分配空間,實(shí)際上是給指針的臨時(shí)變量分配空間,函數(shù)結(jié)束后,這個(gè)臨時(shí)變量也消亡,而str仍然為NULL,沒有為其分配空間,此時(shí)strcpy()是肯定會(huì)出錯(cuò)的。
若改為void GetMemeory(char* &p);則能正常運(yùn)行得到結(jié)果 ThunderDownloader
14、在c++中,
const int i = 0; int *j = (int *) &i; *j = 1; printf("%d,%d", i, *j)輸出是多少?(A)
0,1
1,1
1,0
0,0
解析:
這個(gè)題一定要注意是在C++中的運(yùn)行結(jié)果。
在C語言中
void main(){ const int i = 0; int *j = (int *)&i; *j = 1; printf("%d,%d", i, *j); system("pause"); }結(jié)果輸出為1,1
在C++中
#include<iostream> using namespace std; int main(void){ const int i=0; int *j = (int *)&i; *j = 1; printf("%d,%d", i, *j); system("pause"); return 0; }結(jié)果輸出為0,1
分析:C語言中的const是運(yùn)行時(shí)const,編譯時(shí)只是定義,在運(yùn)行才會(huì)初始化。C語言中const變量不能用于成為數(shù)組長度等作為編譯時(shí)常量的情況,原因就在此。C語言const變量在運(yùn)行時(shí)改變了是可以再次讀出改變后的值的。
C++中,const變量是編譯時(shí)的常量,可以向#define定義的常量一樣使用。故C++中const變量的值在編譯時(shí)就已經(jīng)確定了,直接對cosnt變量進(jìn)行了值的替換,因此當(dāng)const變量的值改變時(shí),const的變量值是不會(huì)得到更新的。
這幾行代碼在C和C++中都會(huì)改變const變量的值,只不過C++中const變量在編譯的時(shí)候已經(jīng)確定了,而C中的const變量可以在運(yùn)行時(shí)改變后再次讀取。以下代碼核實(shí)了C++中的const變量確實(shí)被改變了。
#include<stdio.h> #include<iostream> using namespace std; int main(void){ const int i=0; int *j = (int *)&i; *j = 1;printf("%d,%d\n", i, *j); cout << "i address"<<&i << endl; cout << "j address"<<j << endl;return 0; } 同一個(gè)地址,即同一個(gè)變量。C++中const變量確實(shí)別改變了。i的值沒有更新而已。
這跟編譯器的優(yōu)化編譯有關(guān)。
C++中的常量折疊:指const變量(即常量)值 放在編譯器的符號表中 ,計(jì)算時(shí)編譯器直接從表中取值,省去了訪問內(nèi)存的時(shí)間,從而達(dá)到了優(yōu)化。
printf("%d,%d", i, *j), 因?yàn)閕是const的,第一個(gè)輸出值在編譯期間就已經(jīng)被替換成0了,局部const變量放在棧區(qū),雖不能直接修改但可以通過指針間接修改,
還要注意這是局部的const,全局的就不能修改了
15、在x86的機(jī)器上,int a=0xabcd1234 char b=((char*)&a)[0]請問b是多少(D)
0xa
0x4
0xab
0x34
解析:
x86是小端存儲(chǔ),即高位存儲(chǔ)在高地址,低位存儲(chǔ)在低地址。
int a = 0xabcd1234;
內(nèi)存中 ab cd 12 34,b作為一個(gè)char指針指向的地址為0x34.
高 --> 低
16、12個(gè)高矮不同的人,排成兩排,每排必須是從矮到高排列,而且第二排比對應(yīng)的第一排的人高,問排列方式有多少種?(B)
120
132
145
153
解析:
C(12,6)-C(12,5)=132
卡特蘭數(shù)問題,這是我在??途W(wǎng)答題遇到的第三個(gè)卡特蘭數(shù)問題了,前兩個(gè)分別是50美分1美元那個(gè)排隊(duì)買票問題和6對括號的組合問題。解釋起來有點(diǎn)麻煩,下面慢慢解釋吧:
我們先把這12個(gè)人從低到高排列,然后,選擇6個(gè)人排在第一排,那么剩下的6個(gè)肯定是在第二排.
用0表示對應(yīng)的人在第一排,用1表示對應(yīng)的人在第二排,那么含有6個(gè)0,6個(gè)1的序列,就對應(yīng)一種方案.
比如010101010101就對應(yīng)著
第一排:0 2 4 6 8 10
第二排:1 3 5 7 9 11
問題轉(zhuǎn)換為,這樣的滿足條件的01序列有多少個(gè).
觀察1的出現(xiàn),顯然,在這個(gè)1之前出現(xiàn)的那些0,1對應(yīng)的人要么是在這個(gè)1左邊,要么是在這個(gè)1前面.而且肯定要有一個(gè)0在這個(gè)1前面,也就是要求,0的個(gè)數(shù)不小于1的個(gè)數(shù).
假設(shè)我們不考慮這個(gè)限制條件,那么全部的01排列共有C(2n,n)種,也就是一半0一半1的情況
現(xiàn)在我們要把其中不符合要求的數(shù)量去掉
在任何不符合條件的序列中,找出使得1的個(gè)數(shù)超過0的個(gè)數(shù)的第一個(gè)1的位置,然后在導(dǎo)致并包括這個(gè)1的部分序列中,以1代替所有的0并以0代表所有的1。結(jié)果總的序列變成一個(gè)有(n+1)個(gè)0和(n-1)個(gè)1的序列。而且這個(gè)過程是可逆的,也就是說任何一個(gè)有(n+1)個(gè)0和(n-1)個(gè)1構(gòu)成的序列都能反推出一個(gè)不符合條件的序列,所以不符合條件的序列個(gè)數(shù)為C(2n,n-1)
所以最終結(jié)果就是C(2n,n)-C(2n,n-1)
本題中2n=12
(int *p[10])(int*) int [10]*p(int *) int (*(*p)[10])(int *) int ((int *)[10])*p以上選項(xiàng)都不正確
解析:
int (*(*func)[5])(int *p);
func被一個(gè)圓括號包含,左邊又有一個(gè)*,那么func是一個(gè)指針,跳出括號,右邊是一個(gè)[]運(yùn)算符號,說明func是一個(gè)指向數(shù)組的指針,現(xiàn)在往左看,左邊有一個(gè)*號,說明這個(gè)數(shù)組的元素是指針,再跳出括號,右邊又有一個(gè)括號,說明這個(gè)數(shù)組的元素是指向函數(shù)的指針。總結(jié)一下,就是:func是一個(gè)指向數(shù)組的指針,這個(gè)數(shù)組的元素是函數(shù)指針,這些指針指向具有int*形參,返回值為int類型的函數(shù)。
詳見:http://blog.csdn.net/u011385799/article/details/47783555
2、 一個(gè)進(jìn)程從執(zhí)行狀態(tài)轉(zhuǎn)換到阻塞狀態(tài)的可能原因是本進(jìn)程(BD)。
時(shí)間片完
需要等待其他進(jìn)程的執(zhí)行結(jié)果
執(zhí)行了V操作
執(zhí)行了P操作
解析:
運(yùn)行態(tài):進(jìn)程占用CPU,并在CPU上運(yùn)行;
就緒態(tài):進(jìn)程已經(jīng)具備運(yùn)行條件,但是CPU還沒有分配過來;
阻塞態(tài):進(jìn)程因等待某件事發(fā)生而暫時(shí)不能運(yùn)行; 進(jìn)程在一生中,都處于上述3中狀態(tài)之一。
運(yùn)行---》就緒: 時(shí)間片用完。
就緒---》運(yùn)行:運(yùn)行的進(jìn)程的時(shí)間片用完,調(diào)度就轉(zhuǎn)到就緒隊(duì)列中選擇合適的進(jìn)程分配CPU
運(yùn)行---》阻塞:發(fā)生了I/O請求或等待某件事的發(fā)生
阻塞---》就緒:進(jìn)程所等待的事件發(fā)生,就進(jìn)入就緒隊(duì)列
P操作是阻塞作用
V操作是喚醒作用
3、已知如下代碼,并在兩個(gè)線程中同時(shí)執(zhí)行f1和f2,待兩個(gè)函數(shù)都返回后,a的所有可能值是哪些?(ABCD)
int a = 2, b = 0, c = 0; void f1() { b = a * 2; a = b; } void f2() { c = a + 11; a = c; }413
15
26
解析:
考慮四行代碼的執(zhí)行順序即可(1)b=a*2,c=a+11,a=c,a=b a=4
(2)b=a*2,c=a+11,a=b,a=c a=13
(3)b=a*2,a=b,c=a+11,a=c a=15
(4)c=a+11,a=c,b=a*2,a=b a=26
4、以下程序段的輸出結(jié)果是(A)
char s[]="\\123456\123456\t"; printf("%d\n",strlen(s));12
13
16
以上都不對
解析:
char s[] = "//123456/123456/t";
這樣strlen(s)輸出17.
char s[] = "\\123456\123456\t";
這樣strlen(s)輸出12.
計(jì)算字符串長度時(shí)關(guān)鍵是要注意辨認(rèn)轉(zhuǎn)義字符;
含轉(zhuǎn)義字符的有:
\\ 表示字符 \
\123表示字符 {
\t 表示制表符
這些都是一個(gè)字符。
5、如下程序
#include <iostream> using namespace std;class A { public: A() { printf("A"); } };int main() { A *p1 = new A; A *p2 = (A *)malloc(sizeof(A));return 0; }該程序運(yùn)行結(jié)果為(A)
A
AA
崩潰
不可預(yù)測
解析:
1 A *p1 = new A;
上面這條語句會(huì)創(chuàng)建一個(gè)A對象,輸出一個(gè)A;
1 A *p2 = (A *)malloc(sizeof(A));
sozeof(A)為1,這條語句創(chuàng)建一個(gè)大小為1的A的指針數(shù)組,但是沒有創(chuàng)建任何A對象,因此不輸出A
這題主要是考的new和malloc的區(qū)別,new會(huì)分配內(nèi)存,并調(diào)用類的構(gòu)造函數(shù)創(chuàng)建對象,而malloc只是分配內(nèi)存,不調(diào)用類的構(gòu)造函數(shù)創(chuàng)建對象,這個(gè)程序應(yīng)該用delete p1;顯示釋放掉p1所指的堆上的內(nèi)存,這樣才會(huì)調(diào)用類的析構(gòu)函數(shù),否則不會(huì)調(diào)用。
6、設(shè)有以下宏定義:
#define N 3 #define Y(n)((N+1)*n)則執(zhí)行語句:z=2*(N+Y(5+1));后,z的值為:(C)
38
42
48
54
解析:
#define N 3
#define Y(n)((N+1)*n)//【注意此處n沒有加括號】,所以后面的n并不是(5+1)
z=2*(N+Y(5+1)) =2*(N+(N+1)*5+1)=2*(3+4*5+1)=48
7、 以下描述正確的是?(C)
虛函數(shù)是可以內(nèi)聯(lián)的,可以減少函數(shù)調(diào)用的開銷提高效率
類里面可以同時(shí)存在函數(shù)名和參數(shù)都一樣的虛函數(shù)和靜態(tài)函數(shù)
父類的析構(gòu)函數(shù)是非虛的,但是子類的析構(gòu)函數(shù)是虛的,delete子類對象指針會(huì)調(diào)用父類的析構(gòu)函數(shù)
以上都不對
解析:
delete子類對象是一定會(huì)調(diào)用父類的析構(gòu)函數(shù)的先調(diào)用子類的析構(gòu)函數(shù)然后調(diào)用父類的析構(gòu)函數(shù);如果要調(diào)用父類指向子類的對象,此時(shí)才需要父類的析構(gòu)函數(shù)是虛的。
8、下列運(yùn)算符中,在C++語言中不能重載的是:(C)
*
>=
::
delete
解析:
在C++中,sizeof運(yùn)算符,.成員運(yùn)算符,.*成員指針運(yùn)算符,::作用域解析運(yùn)算符以及?:條件運(yùn)算符不能被重載
9、說明一下++p 與 p++ 的區(qū)別。(B)
沒有區(qū)別
++p更好一些
p++更好一些
和編譯器有關(guān)
解析:
假設(shè)這樣的一個(gè)例子:
int p = -1; int y = 0; y = p++ + ++P;先分析一下它的匯編代碼(沒有優(yōu)化):
subl $40, %esp ; 分配40字節(jié) movl $1, -16(%ebp) ; 存儲(chǔ) p movl $0, -12(%ebp) ; 存儲(chǔ) y movl -16(%ebp), %eax ; 這3步執(zhí)行 p++ leal 1(%eax), %edx movl %edx, -16(%ebp) addl $1, -16(%ebp) ; 這2步執(zhí)行 ++p movl -16(%ebp), %edx addl %eax, %edx ; 相加操作 movl %edx, -12(%ebp) ; 結(jié)果寫回 y 可以看出p++需要3步,++p需要2步,而且修改p的值是不一樣的,看出++p的效率比p++的高。
前++返回對象的引用,效率較高,故選擇++p
10、下面有關(guān)final, finally, finalize的區(qū)別描述錯(cuò)誤的是?(B)
如果一個(gè)類被聲明為final,意味著它不能再派生出新的子類,不能作為父類被繼承
如果一個(gè)方法被聲明為final,可以被覆蓋
finally在異常處理時(shí)提供 finally 塊來執(zhí)行任何清除操作。
Java使用 finalize() 方法在垃圾收集器象從內(nèi)存中清除出去之前做必要的清理工作
解析:
final關(guān)鍵字可用于修飾類、變量和方法。final修飾的類不能被繼承,final修飾的方法不能被重寫,final修飾的變量不可被修改,一旦獲得初始值,該變量就不能被重新賦值。
11、 以下選項(xiàng)中函數(shù)形參不是指針的是?(C)
fun( int ﹡a ){…}
fun( int a [ 10 ] ) {…}
fun( int &p ) {…}
fun( int p[ ]) {…}
解析:
B選項(xiàng)和D選項(xiàng)是將數(shù)組作為函數(shù)參數(shù);A選項(xiàng)是將指針作為函數(shù)參數(shù);
C. 這個(gè)& 是引用,不是取地址.
12、下面程序應(yīng)該輸出多少?(A)
char *c[] = { "ENTER", "NEW", "POINT", "FIRST" }; char **cp[] = { c+3, c+2, c+1, c }; char ***cpp = cp; int main(void) { printf("%s", **++cpp); printf("%s", *--*++cpp+3); printf("%s", *cpp[-2]+3); printf("%s\n", cpp[-1][-1]+1); return 0; }POINTERSTEW
FERSTEPOINW
NEWPOINTW
POINTFIREST
解析:
這個(gè)主要是執(zhí)行順序的問題,我加了一下括號:
printf("%s\n", **(++cpp));
printf("%s\n", (*(--(*(++cpp)))) + 3);
printf("%s\n", *(cpp[-2]) + 3);
printf("%s\n", cpp[-1][-1] + 1);
其中考了指針應(yīng)用,隱含中也考了運(yùn)算符優(yōu)先級的問題(*--*++cpp+3)
c是一個(gè)指針數(shù)組,每個(gè)數(shù)組單元都是一個(gè)指針,指向一個(gè)字符創(chuàng)。
即c[0]="ENTER"......c[3]="FIRST"
由于[]與*運(yùn)算本質(zhì)幾乎是一致的,以下用[]替換*更容易理解。
c[i]=*(c+i)
c和c+i都是char*[]類型,它可以退化成char**類型,它正好是一個(gè)char**數(shù)組
cp[0]=c+3 .....cp[3]=c
引用后cp[0][0]=*(c+3)=c[3]="FIRST"
cp是char**[]類型,它可以退化成char***類型,正好與cpp類型一致。
1>++ccp的值是cp+1 *++p=*(cp+1)=cp[1] **++p=*(cp[1])=c[2]="POINT"
2>運(yùn)算符優(yōu)先級決定運(yùn)算先后關(guān)系
++ccp的值是cp+2 *++p=*(cp+2)=cp[2]=c+1 --*++p=c *--*++p=*(c+0)=c[0]="ENTER"再+3字符串指向"ER"
3>cpp的值為cp+2 cpp[-2]=*(cpp-2)=*(cp+2-2)=cp[0]=c+3再引用*(c+3)=c[3]="FIRST"字符串指到"ST"
4>cpp的值沒變,cpp[-1]=*(cpp-1)=*(cp+2-1)=cp[1]=c+2再[-1]得*(c+2-1)=c[1]="NEW",+1字符創(chuàng)指針指到"EW"
翻來覆去,記得這個(gè)換算關(guān)系式即可,c[i]=*(c+i)。
13、 有如下程序段:
void GetMemeory(char* p) { p = (char*) malloc (100); } void test() { char *str=NULL; GetMemory(str); strcpy(str,”Thunder”); strcat(str+2, “Downloader”);//*(str+2)=u;把Downloader連接到str+2的串尾后 printf(str); }請問運(yùn)行Test函數(shù)結(jié)果是:(D)
Thunder Downloader
under Downloader
Thunderownloader
程序崩潰
解析:
在函數(shù)中給指針分配空間,實(shí)際上是給指針的臨時(shí)變量分配空間,函數(shù)結(jié)束后,這個(gè)臨時(shí)變量也消亡,而str仍然為NULL,沒有為其分配空間,此時(shí)strcpy()是肯定會(huì)出錯(cuò)的。
若改為void GetMemeory(char* &p);則能正常運(yùn)行得到結(jié)果 ThunderDownloader
14、在c++中,
const int i = 0; int *j = (int *) &i; *j = 1; printf("%d,%d", i, *j)輸出是多少?(A)
0,1
1,1
1,0
0,0
解析:
這個(gè)題一定要注意是在C++中的運(yùn)行結(jié)果。
在C語言中
void main(){ const int i = 0; int *j = (int *)&i; *j = 1; printf("%d,%d", i, *j); system("pause"); }結(jié)果輸出為1,1
在C++中
#include<iostream> using namespace std; int main(void){ const int i=0; int *j = (int *)&i; *j = 1; printf("%d,%d", i, *j); system("pause"); return 0; }結(jié)果輸出為0,1
分析:C語言中的const是運(yùn)行時(shí)const,編譯時(shí)只是定義,在運(yùn)行才會(huì)初始化。C語言中const變量不能用于成為數(shù)組長度等作為編譯時(shí)常量的情況,原因就在此。C語言const變量在運(yùn)行時(shí)改變了是可以再次讀出改變后的值的。
C++中,const變量是編譯時(shí)的常量,可以向#define定義的常量一樣使用。故C++中const變量的值在編譯時(shí)就已經(jīng)確定了,直接對cosnt變量進(jìn)行了值的替換,因此當(dāng)const變量的值改變時(shí),const的變量值是不會(huì)得到更新的。
這幾行代碼在C和C++中都會(huì)改變const變量的值,只不過C++中const變量在編譯的時(shí)候已經(jīng)確定了,而C中的const變量可以在運(yùn)行時(shí)改變后再次讀取。以下代碼核實(shí)了C++中的const變量確實(shí)被改變了。
#include<stdio.h> #include<iostream> using namespace std; int main(void){ const int i=0; int *j = (int *)&i; *j = 1;printf("%d,%d\n", i, *j); cout << "i address"<<&i << endl; cout << "j address"<<j << endl;return 0; } 同一個(gè)地址,即同一個(gè)變量。C++中const變量確實(shí)別改變了。i的值沒有更新而已。
這跟編譯器的優(yōu)化編譯有關(guān)。
C++中的常量折疊:指const變量(即常量)值 放在編譯器的符號表中 ,計(jì)算時(shí)編譯器直接從表中取值,省去了訪問內(nèi)存的時(shí)間,從而達(dá)到了優(yōu)化。
printf("%d,%d", i, *j), 因?yàn)閕是const的,第一個(gè)輸出值在編譯期間就已經(jīng)被替換成0了,局部const變量放在棧區(qū),雖不能直接修改但可以通過指針間接修改,
還要注意這是局部的const,全局的就不能修改了
15、在x86的機(jī)器上,int a=0xabcd1234 char b=((char*)&a)[0]請問b是多少(D)
0xa
0x4
0xab
0x34
解析:
x86是小端存儲(chǔ),即高位存儲(chǔ)在高地址,低位存儲(chǔ)在低地址。
int a = 0xabcd1234;
內(nèi)存中 ab cd 12 34,b作為一個(gè)char指針指向的地址為0x34.
高 --> 低
16、12個(gè)高矮不同的人,排成兩排,每排必須是從矮到高排列,而且第二排比對應(yīng)的第一排的人高,問排列方式有多少種?(B)
120
132
145
153
解析:
C(12,6)-C(12,5)=132
卡特蘭數(shù)問題,這是我在??途W(wǎng)答題遇到的第三個(gè)卡特蘭數(shù)問題了,前兩個(gè)分別是50美分1美元那個(gè)排隊(duì)買票問題和6對括號的組合問題。解釋起來有點(diǎn)麻煩,下面慢慢解釋吧:
我們先把這12個(gè)人從低到高排列,然后,選擇6個(gè)人排在第一排,那么剩下的6個(gè)肯定是在第二排.
用0表示對應(yīng)的人在第一排,用1表示對應(yīng)的人在第二排,那么含有6個(gè)0,6個(gè)1的序列,就對應(yīng)一種方案.
比如010101010101就對應(yīng)著
第一排:0 2 4 6 8 10
第二排:1 3 5 7 9 11
問題轉(zhuǎn)換為,這樣的滿足條件的01序列有多少個(gè).
觀察1的出現(xiàn),顯然,在這個(gè)1之前出現(xiàn)的那些0,1對應(yīng)的人要么是在這個(gè)1左邊,要么是在這個(gè)1前面.而且肯定要有一個(gè)0在這個(gè)1前面,也就是要求,0的個(gè)數(shù)不小于1的個(gè)數(shù).
假設(shè)我們不考慮這個(gè)限制條件,那么全部的01排列共有C(2n,n)種,也就是一半0一半1的情況
現(xiàn)在我們要把其中不符合要求的數(shù)量去掉
在任何不符合條件的序列中,找出使得1的個(gè)數(shù)超過0的個(gè)數(shù)的第一個(gè)1的位置,然后在導(dǎo)致并包括這個(gè)1的部分序列中,以1代替所有的0并以0代表所有的1。結(jié)果總的序列變成一個(gè)有(n+1)個(gè)0和(n-1)個(gè)1的序列。而且這個(gè)過程是可逆的,也就是說任何一個(gè)有(n+1)個(gè)0和(n-1)個(gè)1構(gòu)成的序列都能反推出一個(gè)不符合條件的序列,所以不符合條件的序列個(gè)數(shù)為C(2n,n-1)
所以最終結(jié)果就是C(2n,n)-C(2n,n-1)
本題中2n=12
總結(jié)
- 上一篇: 构造函数和析构函数的调用过程
- 下一篇: 部分真题整理3