1. 程式人生 > >C++知識點備忘錄之函式、指標(五)

C++知識點備忘錄之函式、指標(五)

1、引數為空

void say_hi():在C++中,括號為空與在括號中使用關鍵字void是等效的——意味著函式沒有引數。

2、傳遞陣列

為將陣列型別和元素數量告訴陣列處理函式,請通過兩個不同的引數來傳遞他們:

        void fillArray(int arr[],int size);  //OK!

        void fillArray(int arr[size]);   //NO! 

     傳遞常規變數時,函式使用該變數的拷貝;傳遞陣列時,函式使用該變數的地址。

    將陣列地址作為引數可以節省複製整個陣列所需的時間和記憶體。如果陣列很大,則使用拷貝的系統開銷將非常大,程式將需要更多的計算機記憶體,並花費時間來複制大量的資料。

#include <iostream>

using namespace std;
const int ArSize=8;
//int sum_arr(int arr[],int n);
int sum_arr(int *arr, int n);

int main(int argc, char *argv[])
{
    int cookies[ArSize]={1,2,4,8,16,21,64,128};

    cout<<"Address:"<<cookies<<endl;
    cout<<"sizeof cookies:"<<sizeof cookies<<endl;
    int sum=sum_arr(cookies,ArSize);

    cout<<"Total cookies eaten: "<<sum<<"\n";

    sum=sum_arr(cookies,3);
    cout<<"First three eters ate "<<sum<<" cookies.\n";
    sum=sum_arr(cookies+4,4);
    cout<<"Last four enters ate "<<sum<<" cookies.\n";
    return 0;
}


//int sum_arr(int arr[], int n)
int sum_arr(int * arr,int n)
{
    int total=0;
    for(int i=0;i<n;i++)
        total+=arr[i];
    return total;
}

以下兩句話等價:

                int sum_arr(int arr[],int n);

                int sum_arr(int *arr, int n);

3、

當檢測到輸入有問題時,刪除有問題的字元,並重復此操作,直至檢測到有問題的位置之後的緩衝資料都被清空為止。

#include <iostream>
const int Max=5;
using namespace std;
int fill_array(double ar[],int limit);
void show_array(const double ar[],int n);
void revalue(double r,double ar[],int n);

int main()
{
    double properties[Max];

    int size=fill_array(properties,Max);
    show_array(properties,size);
    cout<<"Enter revaluation factor: ";
    double factor;
    cin>>factor;
    revalue(factor,properties,size);
    show_array(properties,size);
    cout<<"Done.\n";
    return 0;

}

int fill_array(double ar[], int limit)
{
    double temp;
    int i;
    for(i=0;i<limit;i++)
    {
        cout<<"Enter value #"<<i+1<<":";
        cin>>temp;

        if(!cin)
        {
            cin.clear();
            while(cin.get()!='\n')
                continue;
            cout<<"Bad input;input process terminated.\n";
            break;
        }
        else if(temp<0)
        {
            break;
        }
        ar[i]=temp;
    }
    return i;
}

void show_array(const double ar[], int n)
{
    for(int i=0;i<n;i++)
    {
        cout<<"Property #"<<i+1<<": $"
           <<ar[i]<<endl;
    }
}

void revalue(double r, double ar[], int n)
{
    for(int i=0;i<n;i++)
        ar[i]*=r;
}

4、指標和const

    1)讓指標指向一個常量物件,可以防止使用該指標來修改所指向的值。

int age=20;
int sum=24;
const int * p=&age;  //ok
*p=10;  //not allowed
p=&sum;  //valid

    2)將指標本身宣告為常量,可以防止改變指標所指向的位置。

int gorp=12;
int chips=114;
int * const p_snack=&gorp;
*p_snack=24;  //valid
p_snack=&chips; //invalid

    3)為什麼不對型別為基本型別的函式引數使用const限定符呢?

      將const限定符用於指標,以防止指向的原始資料被修改。程式傳遞基本型別(如int或double)時,它將按值傳遞,以便函式使用副本。這樣,原始資料將受到保護。

    4)按值傳遞引數和按地址傳遞引數的區別?

   如果glitz是一個結構變數,如何按值傳遞它?如何傳遞它的地址?這兩種方法有何利弊?

                       a、要按值傳遞它,只要傳遞結構民glitz即可。要傳遞它的地址,要使用地址操作符&glitz。

                      b、按值傳遞將自動保護原始資料,但這是以時間和記憶體為代價的。按地址傳遞可節省時間和記憶體,但不能保護原始資料,除非對函式引數使用了const限定符。

                       c、另外,按值傳遞意味著可以使用常規的結構成員表示法(glitz.結構成員),但傳遞指標則必須使用間接成員操作符(glitz->結構成員)。       

5、作為函式的引數時,如果傳遞的引數是實參,則實際上是從原資料地址拷貝資料過來;使用指標時,實際只是傳遞原資料的地址,執行效率更高。