更新時(shí)間:2018-01-24 來源:黑馬程序員 瀏覽量:
在初學(xué)者學(xué)習(xí)編程的過程中的會(huì)遇到一些經(jīng)常會(huì)犯的錯(cuò)誤,也許在我們成長(zhǎng)起來之后會(huì)覺得這些錯(cuò)誤實(shí)在太低級(jí),但是在牛掰的大蝦也是從菜鳥過來的,針對(duì)于初學(xué)者下邊總結(jié)了一些我們會(huì)經(jīng)常遇到的陷阱,希望對(duì)菜鳥們有幫助:
正題:
陷阱1:忽略大小寫的區(qū)別
#include
void main()
{
int a=10;
a+=a;
printf("%d\n",A);
}
這個(gè)很簡(jiǎn)單,是基礎(chǔ),c語言變量區(qū)分大小寫。代碼中的a與A不是同個(gè)變量,編譯出現(xiàn)A沒定義的錯(cuò)誤。
陷阱2:“{}”與“()”使用不當(dāng)造成錯(cuò)誤
#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ù)組每個(gè)元素,編譯{(1,2,3),(4,5,6)};時(shí),先進(jìn)行括號(hào)內(nèi)的逗號(hào)運(yùn)算(取逗號(hào)最后的數(shù)值),編譯生成{3,6};其它元素為0。正確的寫法:{{1,2,3},{4,5,6}};
陷阱3:在if,while,#include,#define,for后直接加分號(hào),如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,程序編譯的時(shí)候提示錯(cuò)誤,無法引用庫(kù)文件;
如果是#define,比如#define a 200;程序在預(yù)編譯的時(shí)候,200;包括分號(hào)一同被替換進(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被定義為無符號(hào)整型變量,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)生的錯(cuò)誤
#include
void main()
{
int i,rst;
i=32767;//這里是turbo c中int類型為16位,c++為32位
rst=i+1;
printf("%d,%d",i,rst);
}
c語言中int占兩個(gè)字節(jié),數(shù)據(jù)最大支持補(bǔ)碼正數(shù)值32767,加1溢出。
陷阱7:除號(hào)/用法導(dǎo)致的錯(cuò)誤
如果除號(hào)的兩邊都為整數(shù),結(jié)果為整數(shù);兩邊有一個(gè)實(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:變量未定義
雖說是人人都清楚的問題,但是還是會(huì)出現(xiàn)。
陷阱9:用scanf輸入數(shù)據(jù)時(shí)忘記加&符號(hào)
#include
void main()
{
int a,b;
printf("輸入兩個(gè)整數(shù)\n");
scanf("%d%d",a,b);
printf("%d%d\n",a,b);
}
scanf第二個(gè)參數(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語言都遇到過這問題,錯(cuò)在輸入a和b時(shí),忘了在ab之間輸入逗號(hào)。
不是任何的場(chǎng)合適合用其他符號(hào)用作數(shù)據(jù)輸入分割。比如scanf(“%s,%d,%s”,&a,&b,&c);a得到的是整個(gè)語句的內(nèi)容。
我提議用空格取代其他符號(hào)分隔數(shù)據(jù),可以減少不必要的錯(cuò)誤。
陷阱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:指針沒被初始化
指針是存放地址的變量,與其他變量相同的是,變量未被賦值時(shí),變量存放著內(nèi)存上原本的值(內(nèi)存的釋放與文件的刪除相類似,內(nèi)存上的數(shù)據(jù)不改動(dòng),除非其他數(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:超出動(dòng)態(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;
}
程序動(dòng)態(tài)分配5字節(jié)的內(nèi)存空間,但是賦值超過了5字符,錯(cuò)誤為賦值的數(shù)據(jù)超過動(dòng)態(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;
}
有必要在這里說說動(dòng)態(tài)內(nèi)存怎么釋放:
內(nèi)存未釋放在程序運(yùn)行時(shí),開始不出現(xiàn)錯(cuò)誤,過多占用內(nèi)存時(shí)會(huì)造成內(nèi)存空間不足而死機(jī)的現(xiàn)象。
本文版權(quán)歸黑馬程序員C/C++學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:黑馬程序員C/C++培訓(xùn)學(xué)院
首發(fā):http://c.itheima.com/