C语言--数组(二)

函数、数组和指针

int sum(int * ar, int n)
{
    int i;
    int total = 0;
    for (i = 0; i < n; i++)   // 使用 n 个元素
        total += ar[i];      // ar[i] 和 *(ar + i) 相同
    return total;
}

这里,第1个形参告诉函数该数组的地址和数据类型,第2个形参告诉函数该数组中元素的个数。

关于函数的形参,还有一点要注意。只有在函数原型或函数定义头中,才可以用int ar[]代替int * ar:
int sum (int ar[], int n);
int *ar形式和int ar[]形式都表示ar是一个指向int的指针。但是,int ar[]只能用于声明形式参数。
第2种形式(int ar[])提醒读者指针ar指向的不仅仅一个int类型值,还是一个int类型数组的元素。

注意 声明数组形参
因为数组名是该数组首元素的地址,作为实际参数的数组名要求形式参数是一个与之匹配的指针。只有在这种情况下,C才会把int ar[]和int * ar解释成一样。也就是说,ar是指向int的指针。由于函数原型可以省略参数名,所以下面4种原型都是等价的:

int sum(int *ar, int n);
int sum(int *, int);
int sum(int ar[], int n);
int sum(int [], int);

保护数组中的数据

C 通常都按值传递数据,因为这样做可以保证数据的完整性。如果函数使用的是原始数据的副本,就不会意外修改原始数据。但是,处理数组的函数通常都需要使用原始数据,因此这样的函数可以修改原数组。有时,这正我们需要的。例如,下面的函数给数组的每个元素都加上一个相同的值:

void add_to(double ar[], int n, double val)
{
    int i;
    for (i = 0; i < n; i++)
        ar[i] += val;
}

然而,其他函数并不需要修改数据。例如,下面的函数计算数组中所有元素之和,它不用改变数组的数据。但是,由于ar实际上是一个指针,所以编程错误可能会破坏原始数据。例如,下面示例中的ar[i]++会导致数组中每个元素的值都加1:

int sum(int ar[], int n) // 错误的代码
{
    int i;
    int total = 0;
    for( i = 0; i < n; i++)
        total += ar[i]++; // 错误递增了每个元素的值
    return total;
}

ANSI C提供了一种预防手段。如果函数的意图不是修改数组中的数据内容,那么在函数原型和函数定义中声明形式参数时应使用关键字const。例如,sum()函数的原型和定义如下:

int sum(const int ar[], int n); /* 函数原型 */
int sum(const int ar[], int n)  /* 函数定义 */
{
    int i;
    int total = 0;
    for( i = 0; i < n; i++)
        total += ar[i];
    return total;
}

以上代码中的const告诉编译器,该函数不能修改ar指向的数组中的内容。如果在函数中不小心使用类似ar[i]++的表达式,编译器会捕获这个错误,并生成一条错误信息。

这样使用const并不是要求原数组是常量,而是该函数在处理数组时将其视为常量,不可更改。这样使用const可以保护数组的数据不被修改,就像按值传递可以保护基本数据类型的原始值不被改变一样。一般而言,如果编写的函数需要修改数组,在声明数组形参时则不使用const;如果编写的函数不用修改数组,那么在声明数组形参时最好使用const。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值