大學C語言考試易錯知識點總結

2021-10-01 18:44:05 字數 4764 閱讀 6146

函式相關

變數相關

陣列相關

結構體相關

庫函式相關

預編譯相關

後記現在不少大學都把c語言作為一門必學的程式語言。而每到這個時候(可以看一下這篇部落格發表日期),正是不少大一學生即將參加c語言考試的時間。

這樣的考試呢,並不能決定你的實踐能力怎麼樣,他考的很多點,我們不知道,也可以在寫**時避免,我們舉個最簡單的例子,運算子優先順序,這恐怕是必考的內容了。但實際上我們寫**並不需要背下這個,我們完全可以通過多加幾個括號解決問題。但是考試它並不會管這些,考試是別人出的題,所以**也是它的。而我們也需要乙個較高的分數,那麼我們應該怎麼辦呢?

沒錯,這篇部落格就是為了這個而誕生的。從cggwz個人的刷題經歷,總結出易錯的一些點,提醒大家在考試中注意,那麼廢話不多說,我們開始吧!

(再強調一遍:這裡大部分是出卷人可能的設誤點,而不一定是你自己寫**的易錯點)

我們以自增為例,字首和字尾的差別有兩點:

優先順序不同,字尾優先順序更高

返回值不同

雖說優先順序不同,但是在兩者之間也就邏輯非和按位取反,貌似不會有太大影響。

而重點是返回值,也就是說,++x返回的是x+1,而x++返回的是原來的x。

而x本身的值都會在返回值以後立刻改變,也就是執行這個表示式後立即改變,比如:

#include

intmain()

這個輸出結果就是3,而不是2.

c語言在計算邏輯運算子的時候是採取短路機制的,也就是說,如果已經可以判斷這個表示式的最終結果,那麼就不再判斷接下來的表示式,相應地,那些表示式也不會被執行。而出題人則喜歡通過放置一些賦值語句在後面,某些學生會因為忽略了短路機制,而誤以為會執行,從而出錯,我們看個例子:

#include

intmain()

這裡輸出是2嗎?

並不是,是3.

因為--z返回的值是0,而後面的邏輯運算子是&&,也就是說無論後面乙個語句真假與否,這個表示式都是假,所以就會觸發短路機制,不再計算後面的++x,從而x的值不會改變。

我們來看個變式:

#include

intmain()

相信你現在應該能知道結果了,輸出就是2.中間的那個–x並不會因為它在中間而被執行。

我們知道c語言中的賦值運算子是有返回值的。

它們的返回值是賦值後被賦值變數的值,而不是賦值符號右邊的表示式的值

比如int a=10;a+=3;這裡的+=返回的就不是3,而是13.

這也適用於型別轉換問題,比如double a;a=2;這裡這個賦值語句的返回值就是2.0,而不是2.

首先強調一下,這個不是函式,雖然它看起來很像。

它運算得到的值是括號內的東西所佔的記憶體大小,它是乙個int型的值。所以sizeof()的表示式是int型表示式。

我們知道c語言裡是需要函式宣告的,如果函式放在主調函式的後面,就需要在主調函式前進行原型宣告。

但是不知道有沒有像我一樣,由於長期把函式放在主調函式的前面(少打幾行字),而在考試時容易忘記宣告這件事。其實網上有不少資訊學競賽題的**,它們絕大多數都是把函式放在主調函式前面,所以這裡也算是乙個提醒吧。

我們知道main函式有三個引數argc,ar**,envp

我們主要提示一下前面兩個。

現在如果我們在命令列執行如下語句:

d:\cgg.exe how are you!

這麼執行後,ar**是4,而不是3,因為d:\cgg.exe也是乙個引數,而它就儲存在ar**[0]中。

這一點千萬不能忘記。

主要是長度的問題,我們知道c中的字串是以乙個空字元作為字串的結尾標誌。所以,我們在賦值時,要注意字元陣列的長度要比字串的長度多1。比如下面這段**是無法通過編譯的:

#include

intmain()

而我們只需要把a的長度改為5就好了。

這是乙個老生常談的問題,但是還是很容易被忽略。所以在這裡再說一下。當遇到一些計算求值類的題,一定要注意把變數初始化,賦初值,比如0.

我們知道c語言中是有轉義字元的。轉義字元以\開頭,所以,我們是不能在一對單引號中間直接放置右斜槓的,還有就是注意,斜槓後如果是十六進製制的表示碼,開頭是x或x,而不是0x或0x

常用的無非是大小寫字母和數字,這時一定需要記住的(除非你是上機考試)。

字元ascii值a65

a97048

cr(回車)

13空格

32我們知道c中的字串一定是以空字元『\0』結尾,而這個空字元是不顯示的。所以有的出題老師會在這裡設坑,比如:"abcde"佔的記憶體大小是多少位元組?雖然是五個字元,但是實際上還有乙個空字元,總共是6位元組。

我們經常會遇到這樣的題,問你某個字元的值是什麼。

這時我們需要尤其小心,尤其是選擇題。

我們舉個例子來說:char a='c'

a的值是什麼?

是c嗎?

如果你說是,那就錯了。

我們只能說a的值是『c』或者67.

想必你應該能明白我想說什麼了。

單引號是不能省去的,這一點尤其重要,缺少了單引號,它就不再是乙個字元了。

這一點很容易忽略,尤其是選擇題,看到c這個選項,一激動就選上了。那就慘了。

這裡只提醒一點,計算範圍的時候不要忘記對於有符號的數,有一位符號位。

在c語言中是允許進行字串拼接的。

也就是說,如果兩對引號包含的字串放在一起,則會被解釋成乙個字串。

比如:

#include

intmain()

這兩個字串都是合法的,且和「helloworld」等價。

這個……恐怕是個程式設計師都會出過的bug,從你初學程式語言到你退休。

考試也可能會出現這個問題,多半是在for迴圈裡出現。

我們可能會經常看到這樣的題,就是另乙個指標等於二維陣列中的某個位址單元,然後對指標進行加一之類的操作,然後問輸出的值。

而我們知道這裡會有兩種不同的效果,一種是行計算,一種是列計算,二者的含義是,行計算,每次加一,位址會移動一行;而列計算,每次加一,位址只會移動一格。

比如:

#include

intmain

(int argc,

char

*ar**)

,,};

char

(*p)[4

];p=a;

printf

("%s",*

(p+1))

;return0;

}

這裡輸出的就是第二個字串i

具體的分類為:

型別計算方式

a計算行

&a[0][0]

計算列a[0]

計算列*a

計算列我們知道我們可以這樣宣告乙個字元陣列:

char a[12]

="helloworld!"

;

但是,字元陣列在被定義之後,是不被允許這樣直接賦值的

比如下面這段**是不會通過編譯的:

char a[12]

;a="helloworld!"

;

這一點在c++中是被允許的,但是c中是不允許的。

所以習慣了寫c++的同學尤其需要注意。

不要忘記了。

這裡我們只舉個例子,比如我們有abc這個結構體,它有變數x,

sizeof(((struct abc*)0)->x)得到的就是x占用的記憶體大小。

這裡的0,只要是int型的量就可以。

注意math.h中有兩個絕對值函式,乙個是abs(),另乙個是fabs()

其中前者是處理整型變數的,而後者是處理浮點型變數的

我們通常會把它們當作輸入輸出語句使用,單獨成行,總是自動忽略它們的返回值,但其實它們是有返回值的。

那麼它們的返回值是什麼呢?

printf的返回值是輸出的資料個數,而scanf的返回值則是讀入的資料個數。

我們可以來看個例題:

#include

intmain()

請問它的輸出結果是什麼?

答案是1:1,2:4

為什麼是4?不知道你是不是想這麼問。

printf中所說的資料個數,其實是把輸出的每個字元都看成乙個單獨的資料,也就是有多少字元加上我們傳入的資料,就是它的返回值。

和scanf、printf一樣,我們經常忽略fclose的返回值,其實他也是有返回值的。

如果成功關閉流,那麼返回0,如果未成功關閉則返回-1。

我們知道巨集定義實際上只是字串的替換,並不是函式一樣的東西,所以我們在做題時也需要嚴格替換,替換完成之前,不要進行任何計算。

我們舉個例子:

答案是多少?54?那就錯了。實際上應該是48.

這裡我們不能把5+1算出來6再帶入,而是直接代入,這樣你就會發現,5和1不是直接加在一起的。

C易錯知識點

參考酷客網,對其進行了簡單整理 1 下面的程式並不見得會輸出 hello std out 你知道為什麼嗎?include include intmain return 0 參 stdout 和stderr 是不是同裝置描述符。stdout 是塊裝置,stderr 則不是。對於塊裝置,只有當下面幾種情...

c語言中,易錯知識點

1.結構體的計算 struct bbb p sizeof struct bbb 16 int main 2.結構體中結構體,共用體中結構體的大小 union aaahalf short kk number struct bbbhalf struct tagccc half long kk 結構體是個...

C 易錯知識點歸納

物件導向開發的四大特性 三字元組 內建型別所佔記憶體大小 單位 位元組 typedef 為乙個已知型別取新名字 列舉 派生資料型別,只有賦值運算子沒有定義算術運算 變數命名 字母 下劃線開頭,可以有數字,不能有標點符號。大小寫敏感。變數宣告 未開闢空間。extern實現,若在其後賦初始值便為定義。變...