C Primer Plus 第10章 數組和指針 10.6 保護數組的內容

這種技術也會帶來一些新的問題。一般C傳遞數據的值,其緣由是要保護原始數據的完整性。函數使用原始數據的一份拷貝,這樣就不會意外的修改原始數據。可是,因爲處理數組的函數直接操做原始數據,因此它可以修改原數據。有時候這正是咱們須要的,好比給某個數組的全部元素加上同一個值;然而也許其餘函數並不但願修改數據,好比只是計算數組中全部元素的和。數組

10.6.1  對形式參量使用 const函數

在k&RC中,避免此類錯誤唯一的方法就是警戒不出錯。ANSI C中有另外一種方法。spa

若是設計意圖是函數不改變數組的內容,那麼能夠在函數原型和定義的形式參量聲明中使用關鍵字const。例如sum()的原型的定義應該以下:設計

int sum (const int ar[],int n);  //原型指針

int sum (const int ar[],int n)   //定義code

{ ... }ip

這告知編譯器:函數應當把ar所指向的數組做爲包含常量數據的數組對待。這樣若是你意外的使用諸如ar[i]++之類的表達式,編譯器將會發現這個錯誤並生成一條錯誤消息,通知您函數試圖修改常量。原型

須要理解的是,這樣使用const並不要求原始數據是固定不變的。這只是說明函數在處理數組時,應把數組看成是固定不變的。使用const能夠對數組提供保護,就像按值傳遞能夠對基本類型提供保護同樣,能夠阻止函數修改調用函數中的數據 。編譯器

總之,若是函數想修改數組,那麼在聲明數組參量時就不要使用const;若是函數不須要修改數組,那麼在聲明數組參量時最好使用const。io

請看程序清單10.14中的程序,其中一個函數顯示數組,另外一個函數對數組的每個元素乘上一個給定的數值。由於第一個函數不須要修改數組,因此使用const;由於第二個函數須要修改數組,因此不使用const。

程序清單10.14  atf.c程序

/*arf.c --處理數組的函數*/
#include <stdio.h>
#define SIZE 5
void show_array (const double ar[],int n);
void mult_array (double ar[],int n,double mult);
int main(void)
{
    double dip[SIZE]={20.0,17.66,8.2,15.3,22.22};

    printf("The original dip array: \n");
    show_array(dip,SIZE);
    mult_array(dip,SIZE,2.5);
    printf("The dip array after calling mult_array(): \n");
    show_array(dip,SIZE);
    return 0;
}
/*顯示數組內容*/
void show_array (const double ar[],int n)
{
    int i;
    for(i=0;i<n;i++)
        printf("%8.3f ",ar[i]);
    putchar('\n');
}
/*用同一個乘數去乘每一個數組元素*/
void mult_array (double ar[],int n,double mult)
{
    int i;
    for(i=0;i<n;i++)
        ar[i]*=mult;
}

輸出結果以下:

The original dip array:
  20.000   17.660    8.200   15.300   22.220
The dip array after calling mult_array():
  50.000   44.150   20.500   38.250   55.550

請注意兩個函數都是void類型的。函數mult_array()確實使數組dip獲得了新的值,但不是使用rerutn機制實現的。

10.6.2  有關const的其餘內容

前面咱們講過可使用const來建立符號常量

const double PI=3.14156;

以上也可使用#define指令實現。但使用const還能夠建立數組常量、指針常量以及指向常量的指針

指向常量的指針不能用於修改數值,考慮如下代碼:

double rates[5]={88.99, 100.12, 59.45, 183.11, 340.5};

const double *pd=retes;  //pd指向數組開始處

第二行代碼把pd聲明爲指向const double 的指針。這樣,就不能使用pd來修改它所指向的數值。

*pd = 29.89;  //不容許

pd[2] = 222.22;  //不容許

rates[0] = 99.99  //容許,由於rates不是常量

不管使用數組符號仍是指針符號,都不能使用pd修改所指向的數據的值。另外須要注意,還可讓pd指向其餘地址:

pd++;  /*讓pd指向rates[1] -這是容許的*/

一般把指向常量的指針用做函數參量,以代表函數不會用這個指針來修改數據。例如,程序清單10.14中函數show_array()的原型能夠以下定義:

void show_array(const double *ar,int n);

關於指針賦值和const有一些規則須要注意。

首先,將常量或很是量數據的地址賦給指向常量的指針是合法的

double rates[5]={88.99, 100.12, 59.45, 183.11, 340.5};

const double locked[4]={0.08, 0.075, 0.0725, 0.07};

const double * pc = rates;  //合法

pc = locked;  //合法

pc = &rates[3];  //合法

然而,只有很是量數據的地址才能夠賦給普通指針

double rates[5]={88.99, 100.12, 59.45, 183.11, 340.5};

const double locked[4]={0.08, 0.075, 0.0725, 0.07};

double * pc = rates;  //合法

pc = locked;  //非法

pc = &rates[3];  //合法

這樣的規則是合理的。不然,您就可使用指針來修改被認爲是常量的數據。

這些規則的實踐結果是:像show_array()這樣的函數能夠接受普通數組和常量數組的名稱做爲實際參數由於兩種參數均可以賦給指向常量的指針:

show_array(rares,5);  //合法

show_array(locked,4);  //合法

可是,像mult_array()這樣的函數不能接受常量數組的名稱做爲參數:

mult_array(rates,5,1.2);  //合法

mult_array(locked,4,1.2);  //非法

所以,在函數參量定義中使用const,不只能夠修護數據,並且使函數可使用聲明爲const的數組。

const還有不少的用法。例如,您可使用關鍵字const來聲明並初始化指針,以保證指針不會指向別處,關鍵在於const的位置:

double rates[5]={88.99, 100.12, 59.45, 183.11, 340.5};

double * const pc = rates;  //pc指向數組的開始處

pc = &rates[2];  //不容許

*pc = 92.99;  //能夠,更改rates[0]的值

這樣的指針仍然能夠用來修改數據,可是它只能指向最初賦給它的地址。

最後,可使用兩個const來建立指針,這樣的指針即不能夠更改所指向的地址,也不能夠修改所指向的數據:

double rates[5]={88.99, 100.12, 59.45, 183.11, 340.5};

const double * const pc = rates; 

pc = &rates[2];  //不容許

*pc = 92.99;  //不容許

相關文章
相關標籤/搜索