函数、递归、函数指针
1.函数的返回值类型不能是数组,但可以将数组作为结构或对象的组成部分来返回
2.按值传递时,函数使用的使参数的拷贝,而不是原来的数据。
3.当且仅当用于函数头或函数原型中时,int *arr 与int arr[ ]含义相同。在其他的上下文中,两者含义并不相同。例如并不能在函数体中使用int tip[ ]来声明指针。
有两个恒等式: arr[i]==*(arr+i);
&arr[i]==arr+i;
4.当参数为数组,传递的并不是数组内容,而是数组的地址、包含的元素类型及元素数目。传递常规变量时,函数将使用变量的拷贝,而传递数组时,函数将使用原来的数组。
5.对函数外声明的数组名调用sizeof函数,获得的数组长度;但是如果对该数组在某函数中传递的地址名调用sizeof,得到的是数组的指针的长度,因为在函数中传递的不是整个数组值而是数组的指针(地址)。
6.由于函数在传递普通参数时采用值传递,函数使用的使数据的拷贝,而传递数组时,接收数组名的函数将会使用原始数据,为了防止函数无意修改数组内容的行为,可在声明形参时使用关键字const。
如: void show_array(const double ar[ ],int n); //并不是说ar是常量数组,而是不允许对ar在函数中进行修改。
同时,由于直接对原始数组进行修改,因此可以在函数中修改数据,而不必将修改后的数据再次进行返回。
7.const类型与指针:
(1)const int* pt = &age; //age是变量不是常量,但pt是一个常量指针。这意味着,age可以更改,但不能通过更改pt指针去改 变它。
(2)可以将const变量的地址给指向const的指针,但不能将const的地址赋给常规指针。
如const float g_earth = 9.80;
const float *pe=&g_earth; //合法
const float g_moon=1.63;
float *pm =&g_moon; //不合法
(3)涉及到指针之间的const赋值时,仅有一级间接关系可以赋值。如&p1赋给const指针p2,则可以使用P1来修改const数据。
8.二维数组做函数的参数时,形如int arr[3][4]和arr(*int )[4],是表示这个数组有三个元素,分别是三个指向四个Int类型的指针。因此在作为函数参数传递时,第一个参数可以省略,第二个不可以。即声明可以为:
int sum(int arr[][4],int size);
9.传递C语言风格的字符串(以‘\0’结尾的字符数组)时,由于内置'\0',因此传参时可以不必传递数组的长度。
10.递归:递归函数调用自己,则被调用的函数也将调用自己,这将无限循环下去,直到代码中包含终止调用链的内容。如:
void recurs(argumentlist) //只要if为true则将一直执行statemetns1调用recurs(),而不会执行statements2。
//当if语句为false,当前调用将执行statements2.当结束后将返回调用recurs执行statements2再结 //束返回给之前的一个调用。
{
statements1;
if(test)
recurs(arguments)
statements2
}
如: int main( )
{
countdown(4);
return 0;
}
void countdown(int n)
{
cout<<"counting down..."<<n<<endl;
if(n>0) countdown(n-1);
cout<<n<<":Kaboom!\n";
}
上述代码输出结果将为:
counting down...4
counting down...3
counting down...2
counting down...1
counting down...0
0:Kaboom!
1:Kaboom!
2:Kaboom!
3:Kaboom!
4:Kaboom!
在这个过程当中,当程序达到第5次调用时,将会有5个地址不同的独立的n变量产生。
11.获取函数的地址: 如process(think);//将函数think的地址作为参数传入process函数
thought(think());//调用函数think,并将它的返回值作为参数传入thought函数