C语言易错题集 第二部
生活随笔
收集整理的這篇文章主要介紹了
C语言易错题集 第二部
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
C語言易錯題集后續(xù)
- 一、共用體相關(guān)(union)
- 二、do,while相關(guān)
- 三、char溢出相關(guān)
- 四、printf()相關(guān)
- 五、++相關(guān)
- 六、 for語句相關(guān)
- 七、calloc()相關(guān)
- 八、define相關(guān)
- 九、溢出相關(guān)
- 十、指針常量,常量指針相關(guān)
- 十一、多重指針相關(guān)
- 十二、指針相關(guān)
- 十三、abs()相關(guān)
- 十四、全局?jǐn)?shù)組、局部數(shù)組賦值相關(guān)
- 十五、double誤差相關(guān)
一、共用體相關(guān)(union)
問題: 共同體變量所占的內(nèi)存長度等于最長的成員的長度。請問這句話的說法是正確的嗎? 答案: 錯誤 共同體類型的特點 (1)同一共同體內(nèi)的成員共用一個存儲區(qū),存儲區(qū)的大小=成員占用字節(jié)長度最大值?!拘枰紤]內(nèi)存對齊】對齊問題:1.一般而言,共用體類型實際占用存儲空間為其最長的成員所占的存儲空間; 2.若是該最長的存儲空間對其他成員的元類型(如果是數(shù)組,取其類型的數(shù)據(jù)長度,例int a[5]為4)不滿足整除關(guān)系,該最大空間自動延伸; 延伸到可以整除為止 (2)在任一時刻,在一個共同體變量中,只有一個成員起作用。 (3)共同體類型中的成員類型可為任意已定義的數(shù)據(jù)類型。二、do,while相關(guān)
執(zhí)行如下代碼, c 的值是:() int a=0,c=0; do{--c;a=a-1; }while(a>0); 答案 : -1 程序最開始執(zhí)行--c,現(xiàn)在c變成了-1,接著執(zhí)行a=a-1,a也變成了-1,再執(zhí)行while語句,while(a>0),判斷為假,退出循環(huán),故c= -1要注意的是: 條件為真,繼續(xù)運行。 do-while 語句的一般形式為 :do語句while( 表達(dá)式 ) ; 這個循環(huán)與 while 循環(huán)的不同在于 : 它先執(zhí)行循環(huán)中的語句 , 然后再判斷表達(dá)式是否為真 , 如果為真則繼續(xù)循環(huán);如果為假 , 則終止循環(huán)。因此 , do-while 循環(huán)至少要執(zhí)行一次 循環(huán)語句 。 使用while語句應(yīng)注意以下幾點: 1 、 while 語句中的表達(dá)式一般是關(guān)系表達(dá)或 邏輯表達(dá)式 ,只要表達(dá)式的值為真 ( 非 0) 即可繼續(xù)循環(huán)。 2 、循環(huán)體如包括有一個以上的語句,則必須用 {} 括起來,組成復(fù)合語句。三、char溢出相關(guān)
#include<stdio.h> int main(void) {char a=101;int sum=200;a+=27;sum+=a;printf("%d\n",sum);return 0; } 問輸出什么 ? 答案: 72char類型的范圍是-128---+127,當(dāng)a+=27 ,之后a的值超出可表示范圍會變?yōu)?span id="ze8trgl8bvbq" class="token operator">-128.200-128=72 我個人關(guān)于位數(shù)溢出的問題,習(xí)慣把它想象為一個輪回 如下圖四、printf()相關(guān)
#include<stdio.h> int main() { int a=666,b=888;printf("%d\n",a,b);return 0; } 程序運行后的輸出結(jié)果是( )。 A 錯誤信息 B 666 C 888 D 666,888 答案 : B printf()函數(shù) 是 從右往左 入棧(計算表達(dá)式),輸出是從左往右 所以: 該題 printf函數(shù)參數(shù)的入棧順序是從右到左(888先入棧,接著666入棧)。 所以從棧里面讀取一個數(shù)據(jù)時,只會讀取最后入棧的數(shù)據(jù),也即666.五、++相關(guān)
有如下定義#define D 2 int x=5;floaty=3.83; char c=′D′; 則下面選項中錯誤的是()。 A x++; B y++; C c++; D D++; 答案: D D是因為我們不能對宏進(jìn)行取地址操作,而++操作是先從內(nèi)存取值到寄存器 然后寄存器加一后再寫入內(nèi)存中必然涉及如地址操作六、 for語句相關(guān)
設(shè) m 和 n 都是 int 類型,那么以下 for 循環(huán)語句,___ for(m=0,n=-1;n=0;m++,n++)n++;A 循環(huán)體一次也不執(zhí)行 B 循環(huán)體執(zhí)行一次 C 是無限循環(huán) D 有限次循環(huán) E 循環(huán)結(jié)束判斷條件不合法 F 運行出錯 答案: A 上機(jī)測試,for循環(huán)的條件判斷語句中,如果使用賦值語句或常量值, 當(dāng)值為0時,不執(zhí)行循環(huán)體, 當(dāng)值為非0時,無限循環(huán)。所以,選A當(dāng) n為0時:
當(dāng) n為1時:
當(dāng) n為-1時:
當(dāng) n為-2時:
可以看出,當(dāng)n值為非0時,無限循環(huán)。
七、calloc()相關(guān)
有以下程序 #include<stdio.h> #include<stdlib.h> void fun( double *pl,double *p2,double *s) {s = ( double*) calloc ( 1,sizeof(double));*s = *pl + *(p2+1); } int main(void) {double a[2]={1.1,2.2};double b[2]={10.0,20.0};double *s=a;fun(a,b,s);printf("%5.2f\n",*s);return 0; } 程序的輸出結(jié)果是? 答案: 1.10編譯器編譯時給指針參數(shù)提供臨時副本 _p,使得_p=p。 如果函數(shù)體內(nèi)的程序修改了_p指向的內(nèi)容,就導(dǎo)致參數(shù)p指向的內(nèi)容也被做了相應(yīng)的修改,因為他們指向同一內(nèi)存空間。 在本例中,_p 申請了新的內(nèi)存,只是把_p 所指的內(nèi)存地址改變了,但是p 絲毫未變(即修改了p本身的值而不是_p指向的對象)八、define相關(guān)
定義宏#define DECLARE(name, type) type name##_##type##_type, 則DECLARE(val, int)替換結(jié)果為()A int val_int_type B int val_int_int C int name_int_int D int name_int_name 答案 : A##是一種分隔連接方式,它的作用是先分隔,然后進(jìn)行強制連接 “name”和第一個“_”之間被分隔了, 所以預(yù)處理器會把name##_##type##_type解釋成4段:“name”、“_”、“type”以及“_type”, name和type會被替換,而_type不會被替換九、溢出相關(guān)
下列代碼的運行結(jié)果() short i=65537; int j=i+1; printf(“i=%d,j=%d\n”, i, j);A i=65537,j=65538 B i=1,j=2 C i=-1,j=0 D i=1,j=65538 答案: B short是2個字節(jié) 范圍為 -32768~~32767 65537-32767=32770 按照循環(huán)要向后走32770下 即32770-32768=2 還有最后兩下 0 1 即向后移動32770下后到1這個位置 所以i=1十、指針常量,常量指針相關(guān)
下面3段程序代碼的效果一樣嗎? int b; (1)const int *a = &b; (2)int const *a = &b; (3)int *const a = &b;A (2)=(3) B (1)=(3) C (1)=(2) D 都不一樣 E 都一樣 答案 C const在*的左邊,則指針指向的變量的值不可直接通過指針改變(可以通過其他途徑改變); 在*的右邊,則指針的指向不可變。簡記為"左定值,右定向"。常量指針: 指針?biāo)赶虻臄?shù)不能改變 例: int const *b; 指針常量: 指針的指向是固定的 例: int *const b;十一、多重指針相關(guān)
A WORLD,LO,SAYHI,EW B WORLD,LO,HI,NEW C NEW,LO,SAYHI,EW D WORLD,LO,HI,EW 答案: D 答案:D; 第一個printf:由于char***cpp,可以讀成cpp為一個指向char**類型的指針,并且初始化為cp, 而cp是一個指針數(shù)組,數(shù)組里面存儲的類型為char**,也就是cpp指向cp[0],故*cpp=cp[0]; 因此++cpp使得cpp指向cp[1],故*++cpp=cp[1];而cp[1]是一個指向c[2]的指針,因此*cp[1] = c[2], 故**++cpp=*cp[1]=c[2],故輸出WORLD;第二個printf:由優(yōu)先級可得知,單目運算符高于算術(shù)運算符;而*和++是單目運算符,+是算術(shù)運算符, 又cpp本身是指向的cp[1],故++cpp使得cpp指向cp[2],故*++cpp則為cp[2],而此時的cp[2]是一個指向c[1]的地址, 故對指向c[1]的指針cp[2]進(jìn)行--,故使得cp[2]指向的是c[0],故*--*++cpp+3=*--cp[2]+3=c[0]+3, 而這里的c[0],其實存放的是指向HELLO字符串的指針故c[0]+3,使得該指針指向HELLO中的第二個L的位置,故輸入LO;第三個printf:由于cpp目前指向的是cp[2],而cpp[-2]是等于*(cpp-2),而在第二個printf時cpp指向cp[2], 則*(cpp-2) = cp[0](注:這里cpp-2后,cpp本身的指針地址沒有改變,因此在第四個printf中,cpp依舊是指向cp[2]), 又cp[0]是一個指向c[3]的指針,對cp[0]進(jìn)行*運算,使得*cp[0]=c[3],故**(cpp-2)=*cpp[-2]=c[3], 同時c[3]是一個指向SAYHI的指針,故c[3]+3,使得指向H的位置,故輸出HI;第四個printf:在第三個printf并沒有改變cpp的地址,故cpp依舊是指向cp[2],又cpp[-1][-1]+1=*(*(cpp-1)-1)+1, 故cpp-1,則cpp指向cp[2],故*(cpp-1)=cp[1];此時的cp[1]是一個指針,指向c[2],故cp[1]-1是從指向c[2]的指針地址-1, 故是指向c[1],則*(*(cpp-1)-1)=*(cp[1]-1)=c[1],故cpp[-1][-1]+1=*(*(cpp-1)-1)+1=c[1]+1,此時的c[1]同樣是一個指針, 故c[1]+1是指向NEW中的E的位置,故輸出EW。 故答案是D。十二、指針相關(guān)
有以下程序段: char *p, *q; p = (char *)malloc(sizeof(char) * 20); q = p; scanf(“%s %s”, p, q); printf(“%s %s\n”, p, q); 若從鍵盤輸入:abc def↙,則輸出結(jié)果是( ) A def def B abc def C abc d D d d 答案 : A p和q是指向同一地址,故答案肯定是輸出一樣的字符串,輸入字符串后,p q最開始指向abc , 當(dāng)輸入def后,開始的地址被覆蓋,一起指向def十三、abs()相關(guān)
math.h的abs返回值() A 不可能是負(fù)數(shù) B 不可能是正數(shù) C 都有可能 D 不可能是0 答案: Cc中的函數(shù)申明為 int abs(int num); 正常情況下, num為0或正數(shù)時,函數(shù)返回num值; 當(dāng)num為負(fù)數(shù)且不是最小的負(fù)數(shù)時(不要問我最小的int類型負(fù)數(shù)是多少), 函數(shù)返回num的對應(yīng)絕對值數(shù),即將內(nèi)存中該二進(jìn)制位的符號位取反,并把后面數(shù)值位取反加一; 當(dāng)num為最小的負(fù)數(shù)時(即0x80000000),由于正數(shù)里int類型32位表示不了這個數(shù)的絕對值,所以依然返回該負(fù)數(shù)。 這就是設(shè)計這個庫函數(shù)的時候為什么把返回值設(shè)置為int而不是unsigned的原因 ,當(dāng)然如果把返回值設(shè)置為unsigned是不是更加合理呢,這個也許有更好的解釋,期待...十四、全局?jǐn)?shù)組、局部數(shù)組賦值相關(guān)
int a[10] = {2,3,5}, 請問a[3]及a[3]之后的數(shù)值是什么?()A 不確定的數(shù)據(jù) B 5 C 0 D 0xffffffff 答案: C1、未初始化的全局?jǐn)?shù)組為0; 2、未初始化的局部數(shù)組為隨機(jī)值; 3、初始化部分的全局?jǐn)?shù)組與局部數(shù)組,初始化部分為初始化值,未初始化部分都為0;(不管全集還是局部)十五、double誤差相關(guān)
以下數(shù)字在表示為double(8字節(jié)的雙精度浮點數(shù))時存在舍入誤差的有()。 A 2的平方根 B 10的30次方 C 0.1 D 0.5 E 100 答案: A B CA. 2的平方根,本身就是無限小數(shù),因此肯定有舍入誤差 B. 10的30次方,明顯超出了double的數(shù)據(jù)存儲范圍,故有舍入誤差 C. 0.1不能用2的負(fù)整數(shù)次方來表示,因此有誤差 D. 0.5 = 2^(-1),因此沒有誤差 E. 100的二進(jìn)制表示是:0110 0100,因此沒有誤差總結(jié):小數(shù)點后的位權(quán)應(yīng)該是2的負(fù)數(shù)次方才沒有誤差,其它的情況都有誤差總結(jié)
以上是生活随笔為你收集整理的C语言易错题集 第二部的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 字符串和字符数组
- 下一篇: 创建一个纯色的背景图