1.運(yùn)行結(jié)果是啥?
fib函數(shù)每遞歸一次cnt就+1 fib就是把大于等于1的數(shù)拆成兩個(gè)數(shù)之和,也就說(shuō)只要fib的變量不是0或1,他就要拆一次,挨著數(shù)出來(lái)就行了
結(jié)果是67
2.這個(gè)代碼的運(yùn)行結(jié)果是?
x后置++,第一次先打印1 然后x變成了2進(jìn)入判斷語(yǔ)句進(jìn)行判斷,判斷的時(shí)候用的是2
后置--x變成了1,然后又回去,導(dǎo)致打印的結(jié)果一直都是1 判斷條件一直都是2
所以運(yùn)行結(jié)果為陷入死循環(huán)
3.下面代碼的運(yùn)行結(jié)果為?
int i=1;
int j;
j=i++;
答:把i的值也就是1先賦給了j,此時(shí)j=1,然后后置++ i變成了2 因此運(yùn)行結(jié)果為2 1
4.k最終結(jié)果是什么?
表達(dá)式也即k=k*(i+j)=3*30=90 其實(shí)就是+的優(yōu)先級(jí)高于*=
5.下面代碼運(yùn)行結(jié)果為?
主函數(shù)里面打印的那個(gè)a應(yīng)該是最上面那個(gè)全局變量a,也就是1,至于test里面那個(gè)a,他是個(gè)局部變量,只能在test函數(shù)里面調(diào)用,出了函數(shù),這個(gè)a的生命周期就結(jié)束了
這個(gè)題告訴我們局部變量和全局變量的名字最好不要沖突
6.c程序的基本組成單位是函數(shù)
c語(yǔ)言只規(guī)定了語(yǔ)法,庫(kù)函數(shù)是獨(dú)立于c語(yǔ)言語(yǔ)法之外的,是利用c語(yǔ)言的語(yǔ)法寫(xiě)出來(lái)的
c語(yǔ)言本身并沒(méi)有輸入輸出函數(shù)
在對(duì)一個(gè)c程序進(jìn)行編譯的過(guò)程中,是不能發(fā)現(xiàn)注釋中的錯(cuò)誤的,因?yàn)樽⑨屧陬A(yù)處理階段就已經(jīng)被刪除了
7.求兩個(gè)數(shù)的最小公倍數(shù)
或
或 輾轉(zhuǎn)相除法
8.
gets() 函數(shù)的功能是從輸入緩沖區(qū)中讀取一個(gè)字符串存儲(chǔ)到字符指針變量 str 所指向的內(nèi)存空間。
三步翻轉(zhuǎn)法1.字符串整體逆序2.每個(gè)單詞逆序
9.
假如給了20塊錢(qián),可以買20瓶水,喝完之后剩下了20個(gè)瓶子,又可以換10瓶水,喝完之后又得到了10個(gè)空瓶子,又換了5瓶水,喝完之后得到了5個(gè)瓶子,可以換兩瓶水,余下了一個(gè)空瓶子,喝完之后又多了倆空瓶子,這時(shí)候就有三個(gè)空瓶子,又可以換一瓶水,喝完之后剩了兩個(gè)空瓶,又換了一瓶水,喝完之后剩下一個(gè)空瓶,至此結(jié)束
通過(guò)測(cè)試了多個(gè)數(shù)字之后由數(shù)學(xué)歸納法可知這個(gè)money和total之間是有規(guī)律的也即total=2*money-1,因此該代碼也可以寫(xiě)成下面這樣
這樣更簡(jiǎn)潔
10.打印菱形 比如輸入7會(huì)出現(xiàn)一個(gè)這樣的菱形
答案:需要有一個(gè)意識(shí):打印多少個(gè)東西,只需要讓循環(huán)進(jìn)行多少次就行
打印這個(gè)圖形無(wú)非就是先打印空格再打印*,那現(xiàn)在問(wèn)題就是打印哪一行應(yīng)該打印多少個(gè)空格,打印多少個(gè)*,以這個(gè)有13行的菱形為例,它是以中間為分界線,上下各六行組成的,把這個(gè)菱形的打印分成上下兩部分來(lái)打印,前七行是上半部分,后六行是下半部分。首先討論上面部分,第一行打印了6個(gè)空格一個(gè)*,第二行打印了5個(gè)空格三個(gè)*,可知如果i是從零開(kāi)始算的話,每行打印line-1-i個(gè)空格,打印了2*i+1個(gè)*,然后是下面部分重新來(lái)一個(gè)for循環(huán),i=0,應(yīng)該打印1個(gè)空格,11個(gè)*,i=1,應(yīng)該打印2個(gè)空格,9個(gè)*,也就是打印i+1個(gè)空格,2*(line-1-i)-1個(gè)*,要想打印i+1個(gè)空格,只需要讓j
11.C程序常見(jiàn)的錯(cuò)誤分類包括編譯錯(cuò)誤,鏈接錯(cuò)誤,運(yùn)行時(shí)錯(cuò)誤。其中運(yùn)行時(shí)錯(cuò)誤指的是語(yǔ)法沒(méi)有問(wèn)題,但是邏輯有問(wèn)題導(dǎo)致的錯(cuò)誤,比如棧溢出就是一種運(yùn)行時(shí)錯(cuò)誤
12.Debug被稱為調(diào)試版本,Release被稱為發(fā)布版本,測(cè)試人員測(cè)試的就是release版本,debug版本包含調(diào)試信息,不做優(yōu)化,release版本不可調(diào)試,而且編譯器往往會(huì)自動(dòng)做一些優(yōu)化,程序大小和運(yùn)行速度上最優(yōu)
13.答案:C
const應(yīng)該放在*的右邊,這樣才能保證p指向的變量值可以修改
14. C
A 中第一個(gè)const修飾的是變量p,第二個(gè)const修飾的是指針p A錯(cuò)誤
B 中第一個(gè)const修飾的是*p,第二個(gè)修飾的是p,B錯(cuò)誤
C中第一個(gè)const和第二個(gè)const都在*的左邊,修飾的都是*p,C正確
D中第一個(gè)是指針數(shù)組,表示一個(gè)數(shù)組里面有是個(gè)元素,每個(gè)元素是int*類型
第二個(gè)是數(shù)組指針,里面存放的是一個(gè)數(shù)組的地址,該數(shù)組里面有十個(gè)元素,每個(gè)元素的類型是int
15.編程實(shí)現(xiàn)
本題的基本思路就是從前面開(kāi)始找偶數(shù),同時(shí)從后面開(kāi)始找奇數(shù),如果前面找到了偶數(shù),后面找到了奇數(shù),就把這兩個(gè)數(shù)交換一下
這里判斷條件之所以寫(xiě)成這樣,是因?yàn)槿绻o的數(shù)組是一個(gè)全為奇數(shù)或者全為偶數(shù)的數(shù)組的話left會(huì)一直++或者right會(huì)一直--,到最后的時(shí)候再++或者--就會(huì)造成越界訪問(wèn)
值得注意的是雖然這個(gè)代碼出現(xiàn)了很多whiile循環(huán),但是只需要用指針把這個(gè)數(shù)組里所有元素地址訪問(wèn)了一遍就行了,其實(shí)效率式非常高的
16.運(yùn)行結(jié)果為?
char類型的a和char類型的b存到了char類型的c里面,首先要發(fā)生整型提升,此時(shí)a+b在內(nèi)存中的二進(jìn)制序列應(yīng)該如圖所示
這個(gè)二進(jìn)制序列在往c里面存放的時(shí)候會(huì)發(fā)生截?cái)啵琧只能存8位,因此存的是00101100
因此如果打印a+b,打印的是沒(méi)有發(fā)生截?cái)嘀暗哪莻€(gè)二進(jìn)制序列,這個(gè)數(shù)其實(shí)是300,如果是打印c,打印的就是發(fā)生截?cái)嘀蟮哪莻€(gè)二進(jìn)制徐磊,這個(gè)數(shù)就是44
17.
大端模式處理器,a如圖存放,這里是為了方便理解直接把這個(gè)0x1234在內(nèi)存中的存儲(chǔ)寫(xiě)成了這樣。(其實(shí)數(shù)據(jù)在內(nèi)存中均是以二進(jìn)制序列存儲(chǔ)的,0x1234是一個(gè)十六進(jìn)制序列而不是說(shuō)是個(gè)十六進(jìn)制的數(shù)一千二百三十四,我可以用這個(gè)十六進(jìn)制序列1234的一每位去換二進(jìn)制序列的四位,最后這個(gè)十六進(jìn)制序列就換了16位二進(jìn)制序列,因?yàn)閍是一個(gè)int類型的,他占四個(gè)字節(jié)也就是32個(gè)比特位,因此我們要補(bǔ)零補(bǔ)夠32位,這時(shí)候把這個(gè)二進(jìn)制序列翻譯成16進(jìn)制序列就是00 00 12 34)
&a就找到了00,但是這里的&a是一個(gè)unsigned int*類型的,現(xiàn)在我們把它強(qiáng)制轉(zhuǎn)換成unsigned char*類型的,這時(shí)候再對(duì)a的地址進(jìn)行解引用,一次就只能訪問(wèn)一個(gè)字節(jié),因此這里取出的是十六進(jìn)制數(shù)00 答案選A
18.
大小端字節(jié)序指的是數(shù)據(jù)在電腦上存儲(chǔ)的字節(jié)順序而不是二進(jìn)制順序
大端字節(jié)序是高位放到低地址,低位放到了高地址
小端字節(jié)序是低位放到了低地址,高位放到了高地址
19.打印楊輝三角
如果我們把楊輝三角的空格去掉就變成了這樣
這個(gè)東西完全可以放到一個(gè)二維數(shù)組里面,可以看到第一列和對(duì)角線上的元素均為1
而第i行第j列的元素等于第i-1行第j-1列元素和第i-1行第j列元素之和,如果想要打印成三角形的樣子,只需要補(bǔ)上一些空格即可,就像前面做的那個(gè)打印菱形的題目一樣
20.
只需分別假設(shè)A B C D 是兇手帶進(jìn)去看看對(duì)不對(duì)即可
21.
首先f(wàn)or循環(huán)羅列出a所有的名次可能性,當(dāng)a是第一名的時(shí)候,b有可能是2345名其中一名,這里先寫(xiě)成12345名的其中一名,后面加一個(gè)限制條件讓五個(gè)人名次不同即可,這樣內(nèi)嵌for循環(huán)就羅列出了所有的名次可能性,要想讓五個(gè)人名次不同,只需要打印之前讓a*b*c*d*e=120即可,名次可能性有很多種,但是滿足每個(gè)人說(shuō)對(duì)一半這個(gè)條件的可能性只有一種,由于在c語(yǔ)言中真為1,假為0,這個(gè)條件也可以翻譯成兩個(gè)命題加起來(lái)等于1。答案如圖。
22.打印X形圖案
打印X形圖案無(wú)非就是打印*和空格,可以先打印一個(gè)矩形,然后在兩條對(duì)角線上打印*,其余位置打印空格。主對(duì)角線上坐標(biāo)特點(diǎn)是行和列相等,次對(duì)角線上特點(diǎn)是加起來(lái)等于n-1。
23.
首先要生成七個(gè)數(shù),那就把scanf放到for循環(huán)里面,就能輸入七次了,每次輸入一個(gè)score之后,都把它加到sum上,這樣等七個(gè)score都輸入完成之后就能得到sum了,但是要求要去掉最大值和最小值,那我們就要把最大值和最小值找出來(lái),至于最大值max,我們讓他的初始值為0,每當(dāng)碰到一個(gè)比他大的數(shù),就把這個(gè)數(shù)賦給max,為什么不初始化成別的數(shù)?因?yàn)橐俏页跏蓟瘋€(gè)80分,七個(gè)評(píng)分都比80要小,那最終max就成80了,而真實(shí)得分并不夠八十。同理最小值min初始化成100,這是因?yàn)槿绻覀儼阉跏蓟杉偃?0,萬(wàn)一每一個(gè)評(píng)分都比八十分要高,那min最終就是80,但是真實(shí)成績(jī)要比80高。最后打印的時(shí)候要求精確到兩位小時(shí)因此寫(xiě)%.2lf即可
24.
輸出某一年的某一個(gè)月有多少天,其實(shí)就是討論二月有多少天,其他月份的天數(shù)都是固定死的??梢韵劝衙總€(gè)月有幾天的信息放在一個(gè)名為days的數(shù)組里面,這里故意在前面多放了一個(gè)元素進(jìn)去,是為了讓月份與下標(biāo)對(duì)應(yīng)起來(lái),即如果輸入的月份是1月,那么就打印31,否則的話輸入一月打印的就成28了,如果是閏年就讓二月份的天數(shù)+1
25.
首先利用for循環(huán)錄入數(shù)據(jù),注意題目中已經(jīng)說(shuō)了是輸入一組升序的數(shù)據(jù),因此這里并不需要再寫(xiě)代碼對(duì)錄入的數(shù)據(jù)進(jìn)行排序,基本思路是拿要插入的數(shù)m和最后的數(shù)比較,如果m比最后的數(shù)小,那就讓最后一個(gè)數(shù)往后挪一位,這樣就有n+1個(gè)位置了,這也是我們創(chuàng)建數(shù)組大小為51個(gè)元素的原因。其實(shí)這個(gè)過(guò)程就是如果arr[i]比m大,那就把a(bǔ)rr[i]拷貝到arr[i+1]上去,然后i--再和m比較,直到m比arr[i]大,這時(shí)候就把m賦給arr[i+1]即可。
當(dāng)m比arr中任何一個(gè)數(shù)都要大,則代碼會(huì)直接執(zhí)行25行的else,把m賦給arr[i+1],就相當(dāng)于把m插入到最后面去,滿足要求。
當(dāng)m比arr中任何一個(gè)數(shù)都要小,如果沒(méi)有32、33行的代碼,因?yàn)閍rr[i]>m這個(gè)判斷條件恒成立,代碼會(huì)一直執(zhí)行24行的語(yǔ)句,最終因?yàn)椴粷M足for循環(huán)的判斷條件而跳出for循環(huán)直接執(zhí)行35行的for循環(huán),打印這個(gè)數(shù)組內(nèi)容,但是在這個(gè)過(guò)程中我們發(fā)現(xiàn)m并沒(méi)有被插入到這個(gè)有序數(shù)列中,為了解決這個(gè)問(wèn)題,需要加上32行的代碼,因?yàn)槿绻鹠比arr中任何一個(gè)數(shù)都要小,最終i會(huì)變成-1,這時(shí)候把m放在數(shù)列的第一個(gè)元素即可。
26.
先看結(jié)構(gòu)體A,第一個(gè)成員變量一定是從偏移量為零的地方開(kāi)始分配內(nèi)存空間,向后分配了四個(gè)字節(jié)的空間到了偏移量為3的位置,然后第二個(gè)變量是short類型的,大小是2個(gè)字節(jié),然后默認(rèn)對(duì)齊數(shù)是4,取二者當(dāng)中較小者因此第二個(gè)成員變量對(duì)齊數(shù)是4,根據(jù)對(duì)其規(guī)則應(yīng)該在偏移量為4的倍數(shù)的地方這里應(yīng)該是從偏移量為4的地方開(kāi)始存放,往下分配兩個(gè)字節(jié)到了偏移量為5的地方,第三個(gè)成員變量是int類型的,對(duì)齊數(shù)為4,因此要從偏移量為4的倍數(shù)的地方也就是偏移量為8的地址開(kāi)始存,往后分配4個(gè)字節(jié)到了偏移量為11的地方,最后一個(gè)char類型的變量對(duì)齊數(shù)是1,直接而存在偏移量為12的地方。目前看起來(lái)是從偏移量為零的位置一直存到了偏移量為12的位置一共存了13個(gè)字節(jié),但是對(duì)其規(guī)則規(guī)定結(jié)構(gòu)體類型的變量大小應(yīng)該是所有變量最大對(duì)齊數(shù)的整數(shù)倍也就是4的整數(shù)倍,因此結(jié)構(gòu)體類型struct A的大小是16個(gè)字節(jié),同理結(jié)構(gòu)體類型struct B的大小是12個(gè)字節(jié)
27.
#pragma pack(4)
#pragma pack(4)表示把默認(rèn)對(duì)齊數(shù)設(shè)置成4,先看structtag Test1類型的結(jié)構(gòu)體變量,第一個(gè)成員變量是short類型的,在創(chuàng)建的時(shí)候在從偏移量為0的位置開(kāi)始,往后分配兩個(gè)字節(jié) 到了偏移量為1的位置,第二個(gè)成員變量是char類型的,對(duì)齊數(shù)是1,往后分配一個(gè)字節(jié)到了偏移量為2的位置,第三個(gè)成員變量是long類型的,對(duì)齊數(shù)是4,從偏移量為4的倍數(shù)的位置也就是偏移量為4的位置開(kāi)始往后分配四個(gè)字節(jié),到了偏移量為7的位置,最后一個(gè)成員變量是long類型的,對(duì)齊數(shù)是4,從偏移量為4的倍數(shù)的位置開(kāi)始存放也就是偏移量為8的位置往后分配4個(gè)字節(jié)到了偏移量為11的位置,自此,從偏移量為0的位置存到偏移量為11的位置,共12個(gè)字節(jié),而12恰好是最大對(duì)齊數(shù)的倍數(shù),因此stT1的大小是12個(gè)字節(jié),同理stT2的大小是12個(gè)字節(jié),stT3的大小是16個(gè)字節(jié)
28.當(dāng)A=2,B=3時(shí),pointer分配了多大的空間?
該題目考查位段,位段的聲明跟結(jié)構(gòu)體類似,但是后面要加一個(gè)冒號(hào)和一個(gè)數(shù)字,后面的數(shù)字用來(lái)限制位段成員最多占用多少個(gè)比特位的空間。
首先宏是用來(lái)整個(gè)替換的,不會(huì)先算好在替換過(guò)去,因此后面算的是sizeof(struct_Record_Struct)*2+3而不是*5。再來(lái)看unsigned char類型的位段成員就一個(gè)字節(jié)一個(gè)字節(jié)的開(kāi)辟空間,因此第一個(gè)成員變量開(kāi)辟了1個(gè)字節(jié)也就是八個(gè)比特位的空間,用了四個(gè)比特位還剩四個(gè)比特位,第二個(gè)成員變量需要兩個(gè)比特位,因此他們就共用一個(gè)字節(jié)即可,然后第三次成員變量不是位段成員,他自己就用去了一個(gè)字節(jié)的空間,第四個(gè)成員變量需要用一個(gè)比特位的空間,但是仍然要為他開(kāi)辟一個(gè)字節(jié)大小的空間,綜上所述,操作系統(tǒng)一共開(kāi)辟了3個(gè)字節(jié)大小的空間,因此最終結(jié)果是3*3+3=9,也即printer指向的空間分配了9個(gè)字節(jié)大小的空間。
29.
首先創(chuàng)建了一個(gè)struct tagPIM*類型的結(jié)構(gòu)體指針pstpimData,然后把puc強(qiáng)制類型轉(zhuǎn)換成struct tagPIM*類型并賦給pstpimData,現(xiàn)在pstpimData就指向了數(shù)組的首元素,但是站在pstpimData的角度看,pstpimData認(rèn)為他指向的是一個(gè)結(jié)構(gòu)體類型,然后利用memset函數(shù)把puc數(shù)組所有內(nèi)容初始化為0,然后對(duì)結(jié)構(gòu)體類型里面的成員變量進(jìn)行初始化,首先把ucpiml初始化為2,因?yàn)閡cpim1不是位段成員,因此這個(gè)2也就是00000010就放到了第一個(gè)字節(jié)的空間里面去,第二個(gè)成員變量是位段成員,他用的是第二個(gè)字節(jié)的內(nèi)容,現(xiàn)在要把他初始化為3,3的二進(jìn)制序列是00000011,但是ucData0只能放一個(gè)比特位,因此就把最后一位1放到了第二個(gè)字節(jié)最左邊的空間里面去。然后要把第三個(gè)成員變量初始化為4,4的二進(jìn)制序列是00000100,ucData1里面只能放2個(gè)比特位,因此初始化的時(shí)候就把最后兩位放到仍然是第二個(gè)字節(jié)里面去,因?yàn)榈诙€(gè)字節(jié)有八個(gè)比特位,剛才ucData0用了1個(gè),還剩七個(gè),完全足夠放下ucData1的2個(gè)比特位,這時(shí)候第二個(gè)字節(jié)還剩下5個(gè)比特位,再來(lái)初始化第四個(gè)成員變量,初始化為5,5的二進(jìn)制序列為00000101,放到ucData2里面去,ucData2只能用3個(gè)比特位,因此就把101放到了仍然是第二個(gè)字節(jié)里面去,此時(shí)內(nèi)存中的二進(jìn)制序列如圖,現(xiàn)在要以16進(jìn)制并且是只打印兩位將puc數(shù)組中打印出來(lái),結(jié)果應(yīng)該是02 29 00 00
30.運(yùn)行結(jié)果為?
本題考查如何計(jì)算聯(lián)合體的大小。操作系統(tǒng)在為聯(lián)合體分配內(nèi)存空間的時(shí)候,也是有對(duì)其規(guī)則的,規(guī)則有二 1.聯(lián)合體類型的大小至少等于其成員變量中較大的那個(gè)2.聯(lián)合體類型的大小是最大對(duì)齊數(shù)的整數(shù)倍。
VS編譯器的默認(rèn)對(duì)齊數(shù)是8,這里第一個(gè)成員變量的對(duì)齊數(shù)是2,占7個(gè)字節(jié),第二個(gè)成員變量的對(duì)齊數(shù)是4,大小是4個(gè)字節(jié),共9個(gè)字節(jié),9并不是最大對(duì)齊數(shù)8的倍數(shù),因此該聯(lián)合體的大小是16個(gè)字節(jié)。
31.運(yùn)行結(jié)果為?
本題考查聯(lián)合體的內(nèi)存分配和大小端字節(jié)序的知識(shí)點(diǎn)。聯(lián)合體中的成員變量共用同一塊內(nèi)存空間,short類型的k是兩個(gè)字節(jié),char類型的數(shù)組i也是兩個(gè)字節(jié),因此只需開(kāi)辟兩個(gè)字節(jié)大小的空間即可。再創(chuàng)建聯(lián)合體的同時(shí)創(chuàng)建了聯(lián)合體類型的指針變量s,和聯(lián)合體類型的a?,F(xiàn)在把a(bǔ)的地址賦給了s,s就指向了聯(lián)合體的這一塊內(nèi)存空間?,F(xiàn)在把i數(shù)組的兩個(gè)元素初始化成0x39和0x38,如圖,然后以16進(jìn)制的形式來(lái)打印k,k也是用的這一塊內(nèi)存空間,因?yàn)閂S 編譯器用的是小端存儲(chǔ)的方式,因此打印結(jié)果應(yīng)該是3839,因?yàn)橹挥羞@樣39才是低位,符合小端存儲(chǔ)低位存在低地址處的原則。
32.運(yùn)行結(jié)果為?
本題考查枚舉類型。枚舉類型默認(rèn)第一個(gè)是0,然后依次+1遞增。這里X1=1,Y1=2,Z1=255,A1=256,B1=257,因此運(yùn)行結(jié)果為1,257
33.
AB顯然正確,C這個(gè)說(shuō)法有歧義,malloc向內(nèi)存申請(qǐng)零字節(jié)內(nèi)存空間這種行為是標(biāo)準(zhǔn)未定義的,取決于編譯器。D中malloc申請(qǐng)了空間不釋放的話會(huì)造成內(nèi)存泄漏
34.
思路:如果這組數(shù)中只有一個(gè)是單著的,那么我們直接用第一個(gè)數(shù)把所有數(shù)異或在一起就可以求出那個(gè)單著的數(shù),這是異或操作符具有a^a=0,a^0=a兩條性質(zhì),如果只有一個(gè)數(shù)是單著的,因?yàn)閯e的數(shù)都是成對(duì)存在的,異或在一起之后就全都是0,一堆0異或完了還是0,最終就是0^單著的那個(gè)數(shù),就可以把這個(gè)數(shù)找出來(lái)了,但是題目中說(shuō)有兩個(gè)是單著的,比如單著的數(shù)是5和6,那么全部異或在一起得到的結(jié)果就是5^6,而我們想要的是單獨(dú)挑出5和6,因此需要先分組,使得分完組之后每一組里面只有一個(gè)單著的數(shù)。至于分組的標(biāo)準(zhǔn),因?yàn)檫@兩個(gè)單著的數(shù)異或在一起的結(jié)果肯定不為零,因?yàn)槿绻Y(jié)果為零表示這些數(shù)是相同的,但是前面說(shuō)過(guò)了他們是單著的數(shù),如果異或完之后的結(jié)果某一位的二進(jìn)制數(shù)是1,說(shuō)明異或的兩個(gè)數(shù)中這個(gè)位置的二進(jìn)制數(shù)不同,那么我們可以依靠這個(gè)特點(diǎn)把這兩個(gè)數(shù)分到兩個(gè)組中去,首先要找到異或的這個(gè)結(jié)果(這里是ret)第幾位是1,那我們可以把ret的每一位都拿出來(lái)看看,看看哪一位是1,利用ret>>i&1就可以拿到ret的每一個(gè)二進(jìn)制位(因?yàn)槎M(jìn)制位不是零就是一,按位與1之后如果本來(lái)是1,按位與之后還是1,是0按位與之后還是零,這樣就拿到了ret的每一個(gè)二進(jìn)制位),此時(shí)的代表的就是ret的二進(jìn)制位右移了多少i位后才找到1,也即兩個(gè)單著的數(shù)二進(jìn)制位不同的位置,這里用新變量pos來(lái)記錄。自此我們就把兩個(gè)單著的數(shù)分到了不同的組去,然后把每一組的數(shù)都按位異或就可以得到每個(gè)單著的數(shù)了。這個(gè)函數(shù)的返回值只能是void類型的,我們可能想要讓他返回這兩個(gè)單著的數(shù),但是返回值只能是一個(gè),怎么返回這兩個(gè)數(shù)呢?可以利用返回型參數(shù),把x和y的地址傳過(guò)去,并利用指針接收他們,同時(shí)在分完組之后把每一組異或在一起之后得到的結(jié)果分別賦給*px和*px,此時(shí)的x和y就被改成了這兩個(gè)單著的數(shù),打印x和y即可得到這兩個(gè)單著的數(shù)。
35.
b表示二進(jìn)制模式,A中沒(méi)有指定用什么方式打開(kāi),B中只是說(shuō)用寫(xiě)的方式打開(kāi),沒(méi)說(shuō)二進(jìn)制,C中表示用二進(jìn)制寫(xiě)的方式打開(kāi)文件,D也沒(méi)有指定打開(kāi)方式,因此答案選C
36.
fopen函數(shù)的返回值需要判斷是否為空指針NULL,才能知道文件是否打開(kāi)成功,因此C錯(cuò)誤,其余選項(xiàng)均正確。一般我們?cè)谟胒open函數(shù)的時(shí)候固定的模式都是FILE* pf=fopen(“test.dat”,“r”);if(pf==NULL){perror(“fopen”);};最后還要fclose(pf);pf=NULL;
37.
文件名不一定包含后綴名,答案選B
在大多數(shù)操作系統(tǒng)中,文件名通常包含后綴名,用于標(biāo)識(shí)文件的類型或格式。后綴名是文件名中最后一個(gè)點(diǎn)(.)之后的字符序列。例如,"document.txt"中的后綴名是"txt","image.jpg"中的后綴名是"jpg"。
但是,C語(yǔ)言中打開(kāi)文件時(shí)并不要求文件名必須包含后綴名。實(shí)際上,C語(yǔ)言中的文件操作函數(shù)并不關(guān)心文件名的具體格式或含義,它們只是根據(jù)提供的字符串來(lái)查找或創(chuàng)建文件。因此,你可以使用任意文件名作為參數(shù)來(lái)打開(kāi)文件,而不一定需要包含后綴名。需要注意的是,包含后綴名的文件名可以幫助操作系統(tǒng)和其他應(yīng)用程序更好地識(shí)別文件的類型,從而進(jìn)行相應(yīng)的處理。因此,在實(shí)際開(kāi)發(fā)中,為了更好地描述文件的內(nèi)容,建議給文件名添加適當(dāng)?shù)暮缶Y。
38.
getchar是適用于標(biāo)準(zhǔn)輸入流(鍵盤(pán))的字符輸入函數(shù),B錯(cuò)誤
39.這個(gè)代碼在干嘛?
fgetc是C語(yǔ)言標(biāo)準(zhǔn)庫(kù)中的一個(gè)函數(shù),用于從打開(kāi)的文件中逐個(gè)讀取字符。
函數(shù)原型如下:
int fgetc(FILE *stream);
參數(shù)stream是一個(gè)指向FILE類型的指針,表示要從中讀取字符的文件流。通常情況下,可以使用fopen函數(shù)打開(kāi)文件并返回的文件指針作為參數(shù)傳遞給fgetc函數(shù)。
fgetc函數(shù)的返回值是讀取到的字符(以u(píng)nsigned char類型返回),或者在讀取到文件結(jié)尾時(shí)返回特殊值EOF(End-Of-File)。EOF是一個(gè)負(fù)數(shù)常量,通常被定義為-1。
可以看到這個(gè)代碼其實(shí)就是在統(tǒng)計(jì)文件中的字符數(shù),答案選B
40.
sprintf是C語(yǔ)言中的一個(gè)標(biāo)準(zhǔn)庫(kù)函數(shù),用于將格式化的數(shù)據(jù)寫(xiě)入字符數(shù)組中。而不是寫(xiě)到輸出流中,答案選D
函數(shù)原型如下:
int sprintf(char *str, const char *format, ...);
參數(shù)str是一個(gè)指向字符數(shù)組的指針,用于存儲(chǔ)格式化后的字符串。這個(gè)字符數(shù)組需要足夠大以容納生成的字符串。
參數(shù)format是一個(gè)格式化字符串,用來(lái)指定輸出的格式。
sprintf函數(shù)的返回值是生成的字符串的字符數(shù)(不包括終止空字符\0)。如果發(fā)生錯(cuò)誤,則返回一個(gè)負(fù)值。
41.
預(yù)處理是C語(yǔ)言編譯過(guò)程中的一個(gè)階段,它在實(shí)際編譯之前對(duì)源代碼進(jìn)行一些預(yù)處理操作。預(yù)處理過(guò)程包括以下三個(gè)主要步驟:
- 文件包含(File Inclusion):通過(guò)#include預(yù)處理指令,將其他文件的內(nèi)容插入當(dāng)前文件中。這樣可以重用其他文件中定義的代碼或聲明??梢园瑯?biāo)準(zhǔn)庫(kù)頭文件(如stdio.h)或用戶自定義的頭文件。
- 宏替換(Macro Substitution):通過(guò)宏定義和宏替換的方式,將源代碼中定義的宏進(jìn)行替換。宏是預(yù)處理器指令,可以用于簡(jiǎn)化代碼,實(shí)現(xiàn)代碼復(fù)用或定義常量。預(yù)處理器會(huì)根據(jù)宏定義將源代碼中的宏名稱替換為相應(yīng)的標(biāo)識(shí)符或表達(dá)式。
- 條件編譯(Conditional Compilation):通過(guò)條件編譯指令(如#if、#ifdef、#ifndef)來(lái)根據(jù)條件判斷選擇性地編譯代碼塊。通過(guò)這些指令可以根據(jù)不同的條件編譯不同的代碼,實(shí)現(xiàn)跨平臺(tái)兼容性、調(diào)試選項(xiàng)等功能。
這三個(gè)過(guò)程執(zhí)行完后,預(yù)處理器會(huì)生成一個(gè)經(jīng)過(guò)預(yù)處理的源代碼文件,其中包含了文件包含、宏替換和條件編譯所引發(fā)的改動(dòng)。然后,這個(gè)經(jīng)過(guò)預(yù)處理的源代碼文件將被傳遞給編譯器進(jìn)行實(shí)際的編譯過(guò)程。答案選A
在預(yù)處理之后,將生成經(jīng)過(guò)預(yù)處理的源代碼文件。然后,該文件將被編譯器進(jìn)一步處理為匯編語(yǔ)言代碼。具體而言,在編譯階段,編譯器將經(jīng)過(guò)預(yù)處理的源代碼翻譯成匯編語(yǔ)言代碼。匯編語(yǔ)言代碼基于特定的硬件體系結(jié)構(gòu)。它使用機(jī)器指令集來(lái)表示特定操作,例如數(shù)據(jù)傳送、算術(shù)運(yùn)算和控制流程等。匯編語(yǔ)言是與機(jī)器語(yǔ)言直接相關(guān)的,每條機(jī)器指令對(duì)應(yīng)一個(gè)特定的操作碼,用于執(zhí)行特定操作。匯編語(yǔ)言代碼更接近于底層硬件,而且十分依賴于具體的計(jì)算機(jī)體系結(jié)構(gòu)。生成的匯編語(yǔ)言代碼可以通過(guò)匯編器(assembler)轉(zhuǎn)化為機(jī)器語(yǔ)言目標(biāo)文件,它包含可以在特定平臺(tái)上運(yùn)行的機(jī)器指令。總結(jié)起來(lái),預(yù)處理、編譯和匯編是C語(yǔ)言編譯過(guò)程中的三個(gè)主要階段。預(yù)處理階段在編譯之前,通過(guò)預(yù)處理器處理源代碼。然后,編譯器將預(yù)處理后的代碼轉(zhuǎn)換為匯編語(yǔ)言代碼,該代碼可以由匯編器轉(zhuǎn)換為機(jī)器語(yǔ)言目標(biāo)文件。
42.
答案:C
鏈接階段是C語(yǔ)言編譯過(guò)程中的最后一個(gè)階段,用于將多個(gè)編譯后的目標(biāo)文件(object files)和庫(kù)文件(library files)合并在一起,生成最終可執(zhí)行文件。
在編譯過(guò)程中,每個(gè)源代碼文件經(jīng)過(guò)預(yù)處理、編譯之后會(huì)生成對(duì)應(yīng)的目標(biāo)文件。這些目標(biāo)文件包含了編譯器所生成的機(jī)器代碼和其他必要的信息,但它們?nèi)匀皇窍鄬?duì)獨(dú)立的,并不能直接運(yùn)行。
在鏈接階段,鏈接器(linker)會(huì)將所有目標(biāo)文件以及所需的庫(kù)文件合并在一起,解決符號(hào)引用(symbol references)和符號(hào)重定位(symbol relocation)的問(wèn)題。符號(hào)引用是指目標(biāo)文件中引用了但未定義的符號(hào)(例如函數(shù)或全局變量),而符號(hào)重定位是指需要調(diào)整目標(biāo)文件中的一些地址或偏移量的指令。
鏈接器完成以下幾個(gè)主要任務(wù):
- 符號(hào)解析(Symbol Resolution):將目標(biāo)文件中的符號(hào)引用與其他目標(biāo)文件中的符號(hào)定義進(jìn)行匹配,建立符號(hào)引用和符號(hào)定義之間的關(guān)聯(lián)。
- 符號(hào)重定位(Symbol Relocation):根據(jù)符號(hào)引用和符號(hào)定義之間的關(guān)系,調(diào)整目標(biāo)文件中的地址或偏移量,確保它們指向正確的位置。
- 符號(hào)合并(Symbol Merging):合并多個(gè)目標(biāo)文件中相同符號(hào)的定義,避免沖突。
- 庫(kù)文件鏈接(Library Linking):將所需的庫(kù)文件中的代碼和數(shù)據(jù)合并到可執(zhí)行文件中,以便程序能夠調(diào)用庫(kù)中提供的函數(shù)和資源。
最終,鏈接器生成一個(gè)完整的可執(zhí)行文件,該文件包含了所有的目標(biāo)文件和庫(kù)文件,可以被操作系統(tǒng)加載和執(zhí)行。
總結(jié)起來(lái),鏈接階段是將編譯后的目標(biāo)文件和庫(kù)文件合并成最終可執(zhí)行文件的過(guò)程。鏈接器解決了符號(hào)引用和重定位問(wèn)題,將各個(gè)編譯單元連接在一起,生成可獨(dú)立運(yùn)行的程序。
43.哪個(gè)不是指針變量?
雖然看起來(lái)兩條語(yǔ)句都是int*a,b,但是INT_PTR只是一個(gè)替換,而int_ptr是一種新的類型,因此再創(chuàng)建a和b的時(shí)候相當(dāng)于int*a;int b,只有一個(gè)*,被a用掉了,b就沒(méi)有*了,只能是int類型
44.
feof函數(shù)用于判斷前一個(gè)讀取操作是否已經(jīng)到達(dá)文件末尾,而不是用于判斷文件是否讀取結(jié)束。這是一個(gè)常見(jiàn)的誤解。
具體來(lái)說(shuō),feof函數(shù)在以下情況下返回非零值(真):
- 在之前的讀取操作中,文件流已經(jīng)到達(dá)了文件末尾。也就是說(shuō),前一個(gè)讀取操作(例如fgets或fscanf)從文件中讀取的是文件的最后一部分,并沒(méi)有繼續(xù)讀取下一個(gè)有效數(shù)據(jù)。
- 在之前的讀取操作中,出現(xiàn)了讀取錯(cuò)誤,如文件被刪除或被其他程序修改等情況。
但是,feof函數(shù)不能可靠地判斷文件的讀取是否已經(jīng)結(jié)束。這是因?yàn)槲募羔樀奈恢檬歉鶕?jù)之前的讀取操作來(lái)確定的,并不能提前知道文件是否已經(jīng)結(jié)束。
為了確定文件讀取是否已經(jīng)結(jié)束,更可靠的方法是檢查讀取操作的返回值。例如,在使用fgets函數(shù)讀取一行數(shù)據(jù)時(shí),如果返回值為NULL,則表示已經(jīng)讀取到文件末尾或者出現(xiàn)了讀取錯(cuò)誤。
下面是一個(gè)示例,使用fgets函數(shù)讀取文件并判斷文件是否讀取結(jié)束:
FILE *file = fopen("file.txt", "r"); if (file != NULL) { char line[100]; while (fgets(line, sizeof(line), file) != NULL) { printf("%s", line); } if (feof(file)) { printf("已到達(dá)文件末尾\n"); } else { printf("讀取文件時(shí)發(fā)生了錯(cuò)誤\n"); } fclose(file); } else { printf("無(wú)法打開(kāi)文件\n"); }
在上述示例中,當(dāng)fgets函數(shù)返回NULL時(shí),程序會(huì)判斷文件是否已經(jīng)結(jié)束,并輸出相應(yīng)的消息。
總結(jié)起來(lái),feof函數(shù)用于判斷前一個(gè)讀取操作是否已經(jīng)到達(dá)文件末尾,而不能可靠地判斷文件的讀取是否已經(jīng)結(jié)束。判斷文件是否讀取結(jié)束應(yīng)該通過(guò)檢查讀取操作的返回值。
45.
選D
在C語(yǔ)言中,沒(méi)有名為#end的預(yù)處理指令或標(biāo)記。通常,C語(yǔ)言中的預(yù)處理指令以#作為前綴,并在指令和其后面的內(nèi)容之間使用空格進(jìn)行分隔。
常見(jiàn)的一些預(yù)處理指令包括:
- #include:用于包含頭文件。
- #define:用于定義宏。
- #ifdef、#ifndef、#else、#endif:用于條件編譯。
- #if、#elif、#else、#endif:用于條件表達(dá)式。
這些預(yù)處理指令通常用于在編譯之前進(jìn)行一些文本替換,或根據(jù)條件編譯不同的代碼。
46.
選D
C語(yǔ)言中有一些預(yù)定義的符號(hào),也稱為預(yù)定義宏(Predefined Macros),它們提供了一些有用的編譯時(shí)信息。預(yù)定義符號(hào)以__開(kāi)頭和結(jié)尾,通常用于條件編譯、平臺(tái)識(shí)別和調(diào)試等方面。
以下是一些常見(jiàn)的預(yù)定義符號(hào):
- __LINE__:表示當(dāng)前源代碼的行號(hào)。
- __FILE__:表示當(dāng)前源文件的文件名。
- __DATE__:表示預(yù)處理的日期,以字符串形式表示,格式為"月 日 年",例如:"Jun 30 2023"。
- __TIME__:表示預(yù)處理的時(shí)間,以字符串形式表示,格式為"小時(shí):分鐘:秒",例如:"03:23:02"。
- __func__:表示當(dāng)前函數(shù)的名稱,用于C99及更高版本。
這些預(yù)定義符號(hào)可以在代碼中使用,通常用于調(diào)試輸出或條件編譯等場(chǎng)景。例如,可以使用__LINE__和__FILE__來(lái)輸出錯(cuò)誤消息并指示出錯(cuò)位置。
#include <stdio.h> int main() { printf("錯(cuò)誤發(fā)生在文件 %s 的第 %d 行\(zhòng)n", __FILE__, __LINE__); return 0; }
輸出結(jié)果可能類似于:
錯(cuò)誤發(fā)生在文件 example.c 的第 5 行
需要注意的是,預(yù)定義符號(hào)是由編譯器提供的,在不同的編譯器或平臺(tái)上可能會(huì)有所不同。因此,在使用預(yù)定義符號(hào)時(shí)應(yīng)謹(jǐn)慎考慮其可移植性。
除了上述列舉的常見(jiàn)預(yù)定義符號(hào)外,不同的編譯器可能還定義了其他額外的預(yù)定義符號(hào),用于特定的編譯器功能或平臺(tái)相關(guān)信息。例如,一些編譯器提供了__cplusplus預(yù)定義符號(hào),用于指示當(dāng)前是否處于C++編譯環(huán)境下。
47.
選A
48.
先把N都替換成4,Y(n)就是((4+2)*n),z就是2*(4+Y(5+1)),Y(5+1)=((4+2)*5+1)=31,因此z就是2*(4+31)=70.
49.運(yùn)行結(jié)果為?
宏是直接原封不動(dòng)的替換,而并不會(huì)提前算好再替換。所以C=2+2*3+3=11
50.
宏由于不用進(jìn)行調(diào)用和返回值,執(zhí)行速度要比函數(shù)更快。因此答案選C
51.
選B
條件編譯指令是用于根據(jù)條件選擇性地編譯代碼的預(yù)處理指令。它允許在編譯時(shí)根據(jù)不同的條件選擇性地包含或排除特定的代碼塊。條件編譯指令在C語(yǔ)言中非常常見(jiàn),可以根據(jù)不同的情況選擇編譯或忽略不同的代碼段。
常見(jiàn)的條件編譯指令包括以下幾個(gè):
- #if、#elif、#else、#endif:這組指令用于基于條件表達(dá)式選擇性地編譯代碼塊。#if指令檢查給定的條件表達(dá)式是否為真,如果為真,則編譯#if和#endif之間的代碼塊;如果為假,則忽略該代碼塊。#elif用于額外的條件檢查,#else用于處理?xiàng)l件不滿足的情況。#endif用于結(jié)束代碼塊。
#if CONDITION_1 // 如果 CONDITION_1 成立,則編譯這里的代碼 #elif CONDITION_2 // 如果 CONDITION_2 成立,則編譯這里的代碼 #else // 如果前面的條件都不成立,則編譯這里的代碼 #endif
- #ifdef、#ifndef、#else、#endif:這組指令用于檢查宏是否已定義。#ifdef檢查宏是否已定義,如果已定義,則編譯#ifdef和#endif之間的代碼塊;#ifndef則相反,只有宏未定義時(shí)才編譯。#else和#endif與之前的示例相同,用于處理?xiàng)l件不滿足的情況。
#ifdef MACRO_NAME // 如果 MACRO_NAME 宏已定義,則編譯這里的代碼 #elif !defined(MACRO_NAME) // 如果 MACRO_NAME 宏未定義,則編譯這里的代碼 #else // 其他情況下編譯這里的代碼 #endif
以上是兩個(gè)常見(jiàn)的條件編譯指令,它們可以通過(guò)編譯時(shí)的條件表達(dá)式或宏的定義與否來(lái)選擇性地編譯代碼。需要注意的是,在使用這些條件編譯指令時(shí),確保在合適的位置使用對(duì)應(yīng)的指令閉合,以避免語(yǔ)法錯(cuò)誤。
52.
尖括號(hào)包含頭文件的時(shí)候會(huì)直接去指定的庫(kù)目錄中尋找,雙引號(hào)包含頭文件的時(shí)候會(huì)先在當(dāng)前源文件所在目錄中找,然后去庫(kù)目錄中找,頭文件中只適合放類型的聲明,包含其他頭文件,函數(shù)的聲明而不要把變量定義放到頭文件中,因?yàn)槿绻竺娑啻我妙^文件的話會(huì)造成變量的重定義。答案選D
53.
并打印交換奇數(shù)位和偶數(shù)位之后的數(shù)。
思路:這個(gè)過(guò)程可以形象的想象一個(gè)數(shù)的二進(jìn)制序列中本來(lái)有32個(gè)比特位,偶數(shù)位在2 4 6 8這樣的位置上,奇數(shù)位在1 3 5 7這樣的位置上,現(xiàn)在我把所有的偶數(shù)位和奇數(shù)位分別單獨(dú)拎出來(lái),然后把偶數(shù)位的這個(gè)序列右移一位,這樣偶數(shù)位就放在了1 3 5 7這樣的位置上,然后把奇數(shù)位的這個(gè)序列左移一位,這樣奇數(shù)位就放到了2 4 6 8這樣的位置上,自此就完成了奇偶位的交換。
先把一個(gè)數(shù)二進(jìn)制序列中的所有偶數(shù)位拿出來(lái),奇數(shù)位全部置成零,得到一個(gè)32個(gè)比特位的二進(jìn)制序列,再把奇數(shù)位全部拿出來(lái),偶數(shù)位全部置成0,得到另一個(gè)32個(gè)比特位的二進(jìn)制序列,如果將第一個(gè)序列右移一位,第二個(gè)序列左移一位,然后加在一起,就能得到奇偶位交換之后的數(shù)的二進(jìn)制序列。比如一個(gè)數(shù)的二進(jìn)制序列為00001111(剩下的位不寫(xiě)了全是零,湊夠32位),那么第一個(gè)序列就是000001010,第二個(gè)序列就是00000101,然后把第一個(gè)序列右移一位,第一個(gè)序列就變成了00000101,第二個(gè)序列左移一位就變成了00001010,再把這兩個(gè)序列加起來(lái)其實(shí)就是奇數(shù)和偶數(shù)位交換之后的數(shù)的二進(jìn)制序列。要得到第一個(gè)序列,只需要讓原來(lái)的數(shù)按位與上一個(gè)0xaaaaaaaaa(這個(gè)東西的二進(jìn)制序列是10101010101010101010101010101010),要拿到第二個(gè)序列,只需要讓原來(lái)的數(shù)按位與上一個(gè)0x55555555(這個(gè)東西的二進(jìn)制序列是01010101010101010101010101010101)。寫(xiě)成常規(guī)的形式就是int ret=((num&0xaaaaaaaa)>>1+(num&0x55555555)>1+(N&0x55555555)
54.offsetof宏的實(shí)現(xiàn)
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-813890.html
將整數(shù)零強(qiáng)制類型轉(zhuǎn)換成結(jié)構(gòu)體指針類型之后,0現(xiàn)在是某個(gè)結(jié)構(gòu)體類型的地址,能訪問(wèn)這個(gè)結(jié)構(gòu)體的成員變量,第一個(gè)成員變量的地址就是0,第二個(gè)成員變量的地址,取決于什么時(shí)候開(kāi)始創(chuàng)建的第二個(gè)變量,也即取決于第一個(gè)成員變量的大小以及對(duì)齊規(guī)則。因?yàn)檫@個(gè)結(jié)構(gòu)體變量開(kāi)辟的內(nèi)存是連續(xù)的,又因?yàn)槊恳粋€(gè)地址對(duì)應(yīng)一個(gè)字節(jié)大小的空間,也就是說(shuō)第一個(gè)成員變量的地址和偏移量都是0,假如第二個(gè)成員變量在偏移量為4的地方被分配空間,他的地址也是4,假如第三個(gè)變量在偏移量為8的地方被分配空間,那他的地址也是8,這時(shí)候成員變量的偏移量等于他的地址,因此將此時(shí)的地址轉(zhuǎn)換成int類型或者size_t類型返回即為偏移量。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-813890.html
到了這里,關(guān)于C語(yǔ)言測(cè)試題(附有詳細(xì)解析)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!