首頁技術(shù)文章正文

C/C++:初學(xué)者常遇到的c語言陷阱

更新時間:2018-01-24 來源:黑馬程序員 瀏覽量:

在初學(xué)者學(xué)習(xí)編程的過程中的會遇到一些經(jīng)常會犯的錯誤,也許在我們成長起來之后會覺得這些錯誤實(shí)在太低級,但是在牛掰的大蝦也是從菜鳥過來的,針對于初學(xué)者下邊總結(jié)了一些我們會經(jīng)常遇到的陷阱,希望對菜鳥們有幫助:

正題:

陷阱1:忽略大小寫的區(qū)別

#include

void main()

{

int a=10;

a+=a;

printf("%d\n",A);

}

這個很簡單,是基礎(chǔ),c語言變量區(qū)分大小寫。代碼中的a與A不是同個變量,編譯出現(xiàn)A沒定義的錯誤。

陷阱2:“{}”與“()”使用不當(dāng)造成錯誤

#include

void main()

{

int i,j;

int a[2][3]={(1,2,3),(4,5,6)};

printf("array a:\n");

for(i=0;i<=1;i++)

{

for(j=0;j<=2;j++)

{

printf("%d",a[i][j]);

}

printf("\n");

}

}

}

程序結(jié)果不能正常輸出數(shù)組每個元素,編譯{(1,2,3),(4,5,6)};時,先進(jìn)行括號內(nèi)的逗號運(yùn)算(取逗號最后的數(shù)值),編譯生成{3,6};其它元素為0。正確的寫法:{{1,2,3},{4,5,6}};

陷阱3:在if,while,#include,#define,for后直接加分號,如for(int a=1;a<10;a++);

如果是while,程序一般執(zhí)行死循環(huán),int a=1;while(a);

如果是if,判斷語句無效果,比如。if(a>0);a=-1;無論a是否大于0,結(jié)果都是a=-1;

如果是#include,程序編譯的時候提示錯誤,無法引用庫文件;

如果是#define,比如#define a 200;程序在預(yù)編譯的時候,200;包括分號一同被替換進(jìn)程序,程序不可能正常編譯

如果是for循環(huán),跟if一樣,事與愿違,循環(huán)做無用功,本想循環(huán)的printf語句只執(zhí)行一次。for(int a=1;a<10;a++);printf("%d",a);程序只輸出一次a值。

陷阱4:使用循環(huán)語句不慎產(chǎn)生死循環(huán)

#include

void main()

{

unsigned int i;

for(i=10;i>=0;i--)

printf("%d",i);

printf("\n");

}

i被定義為無符號整型變量,i的值永遠(yuǎn)大于等于0;i>=0永遠(yuǎn)成立;

陷阱5:do....while與while之間的區(qū)別

do....while先執(zhí)行再判斷條件是否成立;無論條件是否成立,do....while至少執(zhí)行一次;

while 先判斷,再執(zhí)行;條件不成立,就不執(zhí)行,可能執(zhí)行0次;

陷阱6:數(shù)據(jù)溢出產(chǎn)生的錯誤

#include

void main()

{

int i,rst;

i=32767;//這里是turbo c中int類型為16位,c++為32位

rst=i+1;

printf("%d,%d",i,rst);

}

c語言中int占兩個字節(jié),數(shù)據(jù)最大支持補(bǔ)碼正數(shù)值32767,加1溢出。

陷阱7:除號/用法導(dǎo)致的錯誤

如果除號的兩邊都為整數(shù),結(jié)果為整數(shù);兩邊有一個實(shí)數(shù),結(jié)果為實(shí)數(shù);

#include

void main()

{

double i;

i=9.5+1/2;

printf("%f",i);

}

結(jié)果輸出9.500000;這里的1/2運(yùn)算符兩邊為整數(shù),1/2=0;正確的輸出:i=9.5+1.0/2;

陷阱8:變量未定義

雖說是人人都清楚的問題,但是還是會出現(xiàn)。

陷阱9:用scanf輸入數(shù)據(jù)時忘記加&符號

#include

void main()

{

int a,b;

printf("輸入兩個整數(shù)\n");

scanf("%d%d",a,b);

printf("%d%d\n",a,b);

}

scanf第二個參數(shù)必須為地址。正確的寫法:scanf("%d%d",&a,&b);

陷阱10:使用scanf函數(shù)輸入格式不符

#include

void main()

{

int a,b;

scanf("%d,%d",&a,&b);

printf("%d,%d",a,b);

}

凡是學(xué)c語言都遇到過這問題,錯在輸入a和b時,忘了在ab之間輸入逗號。

不是任何的場合適合用其他符號用作數(shù)據(jù)輸入分割。比如scanf(“%s,%d,%s”,&a,&b,&c);a得到的是整個語句的內(nèi)容。

我提議用空格取代其他符號分隔數(shù)據(jù),可以減少不必要的錯誤。

陷阱11:輸入的數(shù)據(jù)類型不符的陷阱

比如在上代碼程序輸入字符'a','b'.輸出不是想要的結(jié)果。改成scanf("%c%c",&a,&b),輸入字符用%c。

陷阱12:switch語句中忘記使用break;

#include

void main()

{

char grade;

scanf("%c",&grade);

switch(grade)

{

case 'a':printf("90-100\n");

case 'a':printf("80-100\n");

}

switch中忘記用break;則每種情況都判斷,滿足條件都執(zhí)行

}

陷阱13:指針沒被初始化

指針是存放地址的變量,與其他變量相同的是,變量未被賦值時,變量存放著內(nèi)存上原本的值(內(nèi)存的釋放與文件的刪除相類似,內(nèi)存上的數(shù)據(jù)不改動,除非其他數(shù)據(jù)覆蓋上去),變量的賦值就是數(shù)據(jù)的覆蓋,內(nèi)存上保存了上次運(yùn)行的數(shù)據(jù)。未被賦值的指針,不知指向哪里。

#include

#include

#include

using namespace std;

int main()

{

char*str;

strcpy(str,"good");

printf("%s",str);

retrun 0;

}

代碼中的str指針未被賦值而使用,程序無法編譯。

陷阱14:超出動態(tài)分配的內(nèi)存

#include

#include

#include

using namespace std;

int main()

{

char*str=malloc(5);

strcpy(str,"goodluck");

printf("%s",str);

free(str);

retrun 0;

}

程序動態(tài)分配5字節(jié)的內(nèi)存空間,但是賦值超過了5字符,錯誤為賦值的數(shù)據(jù)超過動態(tài)分配的空間。

陷阱15:使用內(nèi)存后未釋放

#include

#include

#include

using namespace std;

int main()

{

char*str=malloc(20);

strcpy(str,"goodluck");

printf("%s",str);

retrun 0;

}

有必要在這里說說動態(tài)內(nèi)存怎么釋放:

內(nèi)存未釋放在程序運(yùn)行時,開始不出現(xiàn)錯誤,過多占用內(nèi)存時會造成內(nèi)存空間不足而死機(jī)的現(xiàn)象。


本文版權(quán)歸黑馬程序員C/C++學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!


作者:黑馬程序員C/C++培訓(xùn)學(xué)院


首發(fā):http://c.itheima.com/


分享到:
在線咨詢 我要報名
和我們在線交談!