1. 原型(声明)
double = cube(double x);
//可以没有变量名x,相当于占位符。
关于类型转换:可以由小的类型转换为大类型(int(占16位)——double(占32位))。
通常, 原型自动将被产地的参数强制转换为期望的类型。
2. 函数参数和值传递
作用域:函数中声明的变量(包括参数)是该函数私有的。——局部变量,只在函数内部有效。
值传递:函数cube内传入一个double类型的变量,通过将变量拷贝一份在函数cube内进行操作。(形参)
3. 函数和数组
int sum_arr(int arr[], int n)
值得注意的是第一个传入的参量 int arr[ ] 是传入的数组arr的地址。
也即:int * arr 等价于 int arr[ ]
正如上述函数定义在调用的时候为:
int cookies[size] = {1, 2, 4, 8, 9, 6, 32};
int sum = sum_arr(cookies, size);
//此时函数内部的cookies是数组地址(指针指向的数组第一个元素)
将指针(包括数组名)加1,实际上是加上了一个与指针指向的类型的长度相等的值。对于遍历数组而言,使用指针加法和数组下标和等效的
arr[i] == *(arr + i);
&arr[i] == arr + i;
将数组作为参数意味着传入的是数组第一个元素的地址,并没有将数组的内容传递给函数。函数根据地址使用和操作原来的数组。
总之,传递常规变量时,函数将使用该变量的拷贝;但传递数组时,函数将使用原来的数组。
int sum_arr(int arr[], int n){
int total = 0;
cout<<sizeof(arr) << " = sizeof arr"<< endl;
for(int i = 0; i < n; i++){
total = total + arr[i];
}
return total;
}
//在其他函数中调用sum_arr函数
sum = sum_arr(cookies, size);
sum = sum_arr(coolies + 4, 4);
//都可以
//并且sizeof的结果总是4,指针变量的长度。
//然而,如果在定义int cookies[size] = {1, 2, 4, 8, 9, 6, 32};的函数中写
cout << sizeof(cookies) << " = sizeof cookies " << endl;
//此时的sizeof的结果为cookies整个数组的长度。
4. 指针和const
有两种情况将const关键字用于指针。
(1)让指针指向一个常量对象,这样可以防止使用该指针来修改所指向的值。
(2)将指针本身声明为常量,这样可以防止改变指针指向的位置。
int age = 39;
const int * pt = &age;
//*pt的值将不能被修改
此外,可以将const数据或非const数据的地址赋给指向const的指针,但只能将非const数据的地址赋给非const指针。
//假设有一个由const数据组成的数组:
const int months[12] = {31, 28, 31, 30, 31, 30, 31, 30, 32, 30, 31, 30};
//则禁止将常量数组的地址赋给非常量指针——意味着不能将数组名作为参数传递给使用非常量形参的函数:
int sum(int arr[], int n); //传入的arr[]只能为非const指针
...
int j = sum(months, 12); //错误
上述函数调用将const指针(months)赋给非const指针(arr),编译器将进制这种函数调用。
尽可能使用const
将指针参数声明为指向常量数据的指针有两条理由:
当const修饰指向时
int sloth = 3;
int * const finger = &sloth;
//允许使用*finger修改sloth的值
总之,finger和ps都是const,但是finger和ps不是,此时完全可以修改 *finger 和 ps的值。