C++ 中,向函数传参,是按值传参。(也就是传递的时候会将数值赋给一个新的变量——相当于创建了一个副本,而不是使用原来的那个变量。其中传递给函数的这个值被称为实参(也叫参数),新创建的这个变量称为形参(也叫参量)。)。
函数的形参 也属于 在函数内声明的变量,因此形参的作用范围 也是这个函数。(这种在程序执行过程中自动被分配和释放的变量称为自动变量)
函数的形参是从主程序获取值,而函数内部的局部变量,是在函数内部获取值。
函数是处理负载数据类型的关键手段。(常函数完成一些常见的任务,如将数组名传递给函数,实现数组的元素的累加,该函数的函数头可以定义为 int sun_arr(int arr[],int n),其中 n是数组的长度,arr代表数组名,[]用来指出arr是一个数组,并且[]中内容为空,表示可以将任何长度的数组传递函数。实质上arr接受一个指针作为实参,所以这个函数头也可以写成 int sum_arr(int * arr, iny n)。针对数组的两种写法只在函数头或者函数元原型里等效,在函数体中 int arr[] 和 int * arr 不等效,前者有两个含义,一个是指向int 值 ,一个是指向数组的第一个元素。后者只有一种含义,就是指向int 值)。
对数组名使用sizof将得到整个数组的长度(以字节为单位)。将&用于数组名时,将返回整个数组的地址。
以arr数组为例,数组有两个恒等式。(arr[i] == *(arr+i) ; &arr[i] == arr +i; 从这两个恒等式来看,遍历数组的时候,指针加法 和 数组下标 这两种方式是等效的)
将数组的地址传递给函数之后,函数就可以使用原来的数组(而不是一个副本,这样有很多好处,将数组地址作为参数可以避免复制整个数组,可以节省赋值整个数组所需的时间和内存,因为如果数组很大,拷贝整个数组的系统开销是很大的,需要耗费计算机大量的内存和时间来复制大块的数据。但这种方法也有缺点,就是有可能会破坏原始数组的数据,这个问题可以用const关键字解决。使用const的语法为: int sun_arr( const int arr[],int n); 这个语句中指针 arr指向的是常量数据,也就是说不能使用指针arr来修改数据(这条语句的含义并不是说原始数据是常量数据,只是说不能再函数 sun_arr中使用指针arr来修改原始数据。也就是说sum_arr函数将原始数据视为常量数据,不对其进行修改)。针对普通的按值传参的情况,这种保护机制是自动实现的,因为按值传参通过副本的形式传参,这样是不会出现对原始变量误修改的情况)。
在计算机中内存地址一般是以16进制表示(有些会在地址前加上0x来标识16进制。有些系统其它的进制表示地址如十进制)。
sizeof(数组名)获得的是整个数组的长度,而将数组名作为指针传递给函数之后,sizeof(指针)得到的是指针的内存长度(而不是整个数组的长度了),这就是为什么需要同时把数组长度也作为参数传递给函数的原因。(因为在函数体中,代表数组地址的指针,并没有指出数组的长信息。而元函数外的原数组指针,包含此信息。函数缺少原始数组的一些信息,因此不能使用sizeof来在函数体中获取原始数组的长度,必须依赖传入的元素数来获取次信息)
数组名+4 = 数组的第5个元素的地址。
将数组名和数组长度作为参数传递给函数时,必须将二者分开传递。(正确的函数体语法为 int sun_arr(int arr[],int n); 而不能写成 int sun_arr(int arr[n]); 。第二种语法是错误的)
通过设计函数来处理数据,可以是程序更可靠、修改和调试更方便。(构思程序时将存储属性与操作结合起来,便是朝着OOP思想迈进了一步)
可以设计一个函数来填充数组。
首先考虑根据数据选取 数据类型,并设计不同功能的函数来处理数据。然后将这些函数组合成一个程序。(这种程序设计方法,称为自下而上的程序设计。这种思想就是OOP,设计过程从组件到整体来实现,它强调的是对数据表示和操纵。传统的过程性编程倾向于从上而下进行程序设计,就是首先确定模块化设计方案,然后在研究细节。 不论是传统的过程性编程还是OOP编程,最终的产品都是模块化的程序,这两种编程方式在实际应用都是非常有用的)
将数组信息传递给函数,除了使用 指针+长度数值 这种方式外,还可以使用两个指针的方法(指定元素的区间范围,一个指针标识数组的开头,一个指针标识数组的结尾。C++的STL库将这种使用区间标识数组的方法广义化了。STL使用“超尾”概念来指定区间)。
double elbuod[20];(以该数组定义为例,数组名elboud指向第一个元素, elboud+19指向最后一个元素,elboud+20指向再后面的一个位置。elboud 和 elboud+20 就定义了这个数组的区间,将这个区间传递给函数——将告诉函数应处理的元素范围)
可以让指针指向 const对象 (这样就不能用指针来修改 指针所指向的值。这里只是说不能通过这个指针来修改,但指针所指向的值可以通过其他方法修改),也可以将指针本身声明为const对象, 这样就不可以修改指针本身的值。(这两种用法,都是通过const来实现,可以 const指针可以指向任何 对象,但是const对象的指针必须也为const指针——通过强制类型转换可以吧const对象转换为普通对象,这样就可以使用任何指针)
一般不对多重指针使用 const