1. 程式人生 > >C/C++入門易錯點及常用小技巧

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

a=0;的寫法是不允許的),但在C++中可以

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){}
};

注意:如果自己重新定義了建構函式,則預設生成的建構函式就會被覆蓋. 如果想不經初始化就定義結構體變數需手動加上.