C/C++入門易錯點及常用小技巧
1. int型 :絕對值在10^9範圍內的整數都可以定義成int型。
2. long long型 :如果long long型賦值大於2^31 -1的初值,則需要在初值後面加上LL,否則會編譯錯誤。
3. float、double輸入輸出格式 :使用printf("%f",c);語句時,%f是float和double型的輸出格式。而在使用scanf輸入時,float輸入格式為%f,double輸入格式為%lf。
4. if條件 :由於if(n)表示if(n!=0),所以if(!n)表示if(n==0)
5. for語句 :注意在C語言中不允許在for(A;B;C)語句的表示式A裡定義變數(比如int
6. 陣列定義 :如果陣列大小較大(10^6級別以上),則需要將其定義在主函式外面,否則會使程式異常退出。
7. 陣列賦初值 :如果我們定義一個數組int array[10]={12,1,6,4}.可知只對陣列的前四項賦值,那麼後面沒有賦值的元素預設為0.但如果該陣列沒有賦初值,陣列中的每個元素都可能會是一個隨機數(不一定是0)。所以如果想給整個陣列都賦值為0,簡單介紹以下四種方法:
1、int array[10]={};
2、int array[10]={0};
3、memset函式 :memset(array,0,sizeof(array));//若陣列為int array[10],則此處sizeof(array)=4*5=20,因為
memset是按位元組賦值. 格式 memset(陣列名,值,sizeof(陣列名));
4、fill函式 :fill(array,array+5,8);//陣列從array[0]到array[4]均被賦值為8,格式 fill(起始地址,結束地址,值);
注意:memset()函式需標頭檔案<cstring>或<string.h>. 且memset()只能為陣列賦初值0和-1,因為memset()只能以位元組為單位賦值
fill()函式需標頭檔案<algorithm>. 且fill()可以為陣列或容器的某段區域賦某個任意相同的值.
8. 二維陣列賦值 :若二維陣列array[4][5]={{1,2,3,4,5},{2,2,3},{},{4,2,3,5}};可以看出第三行用{}跳過了(如果不加大括號是無法通過編譯的)
9. 字元陣列初始化 :字元陣列可以通過直接賦值字串來初始化(僅限初始化,程式其他位置不允許這樣直接賦值整個字串)
10. 字元陣列輸入輸出 :定義char str[10]; scanf("%s",str); pritnf("%s",str); 注意字元陣列在輸入時不需要加&取地址運算子. 且scanf輸入時%s通過空格或換行來識別一個字串的結束 gets用來輸入一行字串.gets識別換行符\n作為輸入結束,因此scanf晚一個整數後如果要使用gets,需要先用getchar接收整數後的換行符;puts輸出一行字串後會緊跟一個換行(\n)
11. 字元陣列長度的重要性 :字元陣列的長度一定要比實際儲存字串的長度至少多1,作為結束符'\0'.注int型陣列不需要. 且如果不是使用scanf函式的%s格式或gets函式輸入字串(例如getchar),一定要手動早輸入的每個字串後加‘\0',否則printf和puts輸出字串將無法識別字符串末尾而輸出一大堆亂碼.
12. sscanf與sprintf :
sscanf : int n; char str[10]="123"; sscanf(str,"%d",&n); //sscanf寫法的作用是把字元陣列str中的內容以"%d"的格式寫到n中(從左往右). sscanf還支援正則表示式.
sprintf : int n; char str[10]="123"; sprintf(str,"%d",n); //sprintf寫法的作用是把n以"%d"的格式寫到str字元陣列中(從右往左)
13. 引用& :注意要把引用的&與取地址運算子&區分開. 引用並不是取地址的意思,引用不產生副本,而是給原變數起了個別名 .由於引用是產生變數的別名,因此常量不可以使用引用。所以:
#include <cstdio>
void swap(int* &p1, int* p2){
int* temp=p1;
p1=p2;
p2=temp;
}
int main(){
int a=4,b=5;
int *p1=&a, *p2=&b;
swap(p1,p2);
cout<<a<<","<<b<<endl; //輸出:4,5
cout<<*p2<<","<<*p2<<endl; //輸出5,4
return 0;
}
其中不可以直接寫成swap(&a,&b),而必須用指標變數p1和p2存放&a和&b,然後把指標變數作為引數傳入.
14. 訪問結構體內的元素 :
struct studentInfo{
int id;
char name[30];
studentInfo* next;//指標next用於指向下一個學生地址
}stu,*p;
於是訪問stu中變數的寫法:
stu.id
stu,name
stu.next
訪問指標變數p中的元素的寫法:
(*p).id <=> p->id
(*p).name <=> p->name
(*p).next <=> p->next
15. 結構體的初始化
struct studentInfo{
int id;
char gender;
//法一:stu.id=1001;stu.gender="F";
//預設生成的建構函式
studentInfo(){}
//含參構造器,注意引數名不要與已有引數重名
studentInfo(int _id){
//賦值
id=_id;
}
//建構函式也可以簡化成一行
studentInfo(int _id, char _gender):id(_id),gender(_gender){}
};
注意:如果自己重新定義了建構函式,則預設生成的建構函式就會被覆蓋. 如果想不經初始化就定義結構體變數需手動加上.