🍌const
2021-1-22
| 2023-8-2
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 
 
编写一个处理基本类型的函数时,要选择是传递int类型的值还是传递指向int的指针。通常都是直接传递数值,只有程序需要在函数中改变该数值时,才会传递指针。
对于数组别无选择,必须传递指针,因为这样做效率高。如果一个函数按值传递数组,则必须分配足够的空间来储存原数组的副本,然后把原数组所有的数据拷贝至新的数组中。如果把数组的地址传递给函数,让函数直接处理原数组则效率要高。
 
传递地址会导致一些问题。C 通常都按值传递数据,因为这样做可以保证数据的完整性。如果函数使用的是原始数据的副本,就不会意外修改原始数据。但是,处理数组的函数通常都需要使用原始数据,因此这样的函数可以修改原数组。有时,这正是我们需要的。例如,下面的函数给数组的每个元素都加上一个相同的值:
因此,调用该函数后,prices数组中的每个元素的值都增加了2.5:
该函数修改了数组中的数据。之所以可以这样做,是因为函数通过指针直接使用了原始数据。
 
然而,其他函数并不需要修改数据。例如,下面的函数计算数组中所有元素之和,它不用改变数组的数据。但是,由于ar实际上是一个指针,所以编程错误可能会破坏原始数据。例如,下面示例中的ar[i]++会导致数组中每个元素的值都加1:
 

对形式参数使用const

在K&R C的年代,避免类似错误的唯一方法是提高警惕。ANSI C提供了一种预防手段。如果函数的意图不是修改数组中的数据内容,那么在函数原型和函数定义中声明形式参数时应使用关键字const:
以上代码中的const告诉编译器,该函数不能修改ar指向的数组中的内容。如果在函数中不小心使用类似ar[i]++的表达式,编译器会捕获这个错误,并生成一条错误信息。
这样使用const并不是要求原数组是常量,而是该函数在处理数组时将其视为常量,不可更改
一般而言,如果编写的函数需要修改数组,在声明数组形参时则不使用const;如果编写的函数不用修改数组,那么在声明数组形参时最好使用const。
notion image
 
 

const的其他内容

如果程序稍后尝试改变数组元素的值,编译器将生成一个编译期错误消息:
 
 
指向const的指针不能用于改变值
无论是使用指针表示法还是数组表示法,都不允许使用pd修改它所指向数据的值。但是要注意,因为rates并未被声明为const,所以仍然可以通过rates修改元素的值。另外,可以让pd指向别处:
 
指向 const 的指针通常用于函数形参中,表明该函数不会使用指针改变数据。
 
关于指针赋值和const需要注意一些规则。首先,把const数据或非const数据的地址初始化为指向const的指针或为其赋值是合法的:
然而,只能把非const数据的地址赋给普通指针:
这个规则非常合理。否则,通过指针就能改变const数组中的数据。
应用以上规则的例子,如show_array()函数可以接受普通数组名和 const数组名作为参数,因为这两种参数都可以用来初始化指向const的指针:
因此,对函数的形参使用const不仅能保护数据,还能让函数处理const数组。
 
另外,不应该把const数组名作为实参传递给mult_array()这样的函数:
C标准规定,使用非const标识符(如,mult_arry()的形参ar)修改const数据(如,locked)导致的结果是未定义的。 const还有其他的用法。例如,可以声明并初始化一个不能指向别处的指针,关键是const的位置:
可以用这种指针修改它所指向的值,但是它只能指向初始化时设置的地址。 最后,在创建指针时还可以使用const两次,该指针既不能更改它所指向的地址,也不能修改指向地址上的值:
  • C
  • 指针指针和多维数组
    目录