一、(基础)
1、函数在定义前必须生命函数的类型,既为返回值类型+函数名+(形参)+";"。
()内作用是为代表其内为啥类型的数据,实参变量必须为确定值,形参在定义函数中代替实参位置,为一般变量使用,形参和实参类型必须相同。
2、参数传递分为
①按值传递
②指针地址传递
③引用传递
①:
实参和形参之间互不影响,当函数运行结束后,形参的内存空间被释放,同时函数返回值(如果有的话),以此发挥作用。
②:
即为将形参定义为指针变量,实参即为地址,和①不同的是实参将储存地址传递给形参,实参和形参的指针都指向一个地址,形参地址中内容改变时实参也改变。
指针变量定义为类型标识符+"*"+变量名,"&"+变量名为取地址运算,"*"+指针变量为取内容运算。
当把数组名赋值给指针变量,数组名为起始地址,int *p=a,int *p=&a[0],都为赋初值。
p+1指向下一个元素而不是下一个字。*(p+1)=2即为a[1]=2。
a+i表示a[i]地址&a[i].
因此*(a+i)=a[i].
可以用指针传递不确定个数的数组.
指针传递可得到多个变化的值。
实参指针调用前必须赋值。
③:
变量类型&引用名=变量名。
int &b=a;(b为a别名)。
对b改变即为对a改变。
引用名为变量的别名,不会被分配空间。
引用名只能对应一个变量名。
传引用更容易阅读,改变形参时同时改变实参。
用一个代码解释上三种传递方式:
#include<iostream>
using namespace std;
void swap1(int a, int b) { //按值传递
int tmp = a;
a = b;
b = tmp;
}
void swap2(int* a, int* b) {//传递指针
int tmp = *a;
*a = *b;
*b = tmp;
}
void swap3(int& a, int& b) {//传递引用
int tmp = a;
a = b;
b = tmp;
}
int main() {
int a = 1; int b = 2;
swap1(a, b);
printf("a=%d b=%d \n", a, b); //a=1,b =2
int c = 1; int d = 2;
swap2(&c, &d);
printf("c=%d d=%d \n", c, d); //a=2,b=1
int e = 1; int f = 2;
swap3(e, f);
printf("e=%d f=%d \n", e, f); //e=2,f=1
}
用指针输出数组:
int main( )
{ int a[10], i;
int *p;
for (i=0; i<10; i++)
cin>>a[i];
for (p=a; p<a+10; p++)
cout<<*p<<‘\t’;
}
或
int main( )
{ int a[10], i;
int *p=a;
for (i=0; i<10; i++)
cin>>a[i];
for (i=0; i<10; i++)
cout<<*p++<<‘\t’;
}
二、(题型)
题型主要为调用一次函数
例如:求10的阶乘
#include<iostream>
using namespace std;
int js(int);
int main()
{
int sum=0;
for(int i=1;i<=10;++i)
sum+=js(i);
cout<<"sum="<<sum<<endl;
return 0;
}
int js(int n)
{
int s=1;
for(int i=1;i<=n;++i)
s*=i;
return s;
}
定义函数中调用定义函数
例如:
求俩数最小公倍数
#include<iostream>
using namespace std;
int x,y;
int gcd(int x,int y)
{
int r=x%y;
while(r)
{
x=y;
y=r;
r=x%y;
}
return y;
}
int lcm()
{
return x*y/gcd(x,y);
}
int main()
{
cin>>x>>y;
cout<<lcm()<<endl;
return 0;
}
//上述函数中x,y用全局变量,因此变量值共享,但同时亦有副作用,使用过多会增加调试困难。
同时有递归函数等,即函数自己调用其自身,使n不断减小直到可直接得出结果后,再回溯
得出最终结果。
例如:
求 x的n次方的值
#include<iostream>
using namespace std;
int xn(int);
int x;
int main()
{
int n;
cin>>x>>n;
cout<<xn(n)<<endl;
return 0;
}
int xn(int n)
{
if(n==0)return 1;
else return x*xn(n-1);
}
除以上题型外,函数还会结合其他算法的题型等。
三、(感悟)
按值传递易理解但形参与实参无关,形参不对实参有影响,地址传递虽可以,但形式复杂不易阅读,且易产生错误,而引用完美解决了上述两个问题。
全局变量在简单自定义函数中虽好用,但在复杂情况下,应适当使用,防止因变量值的改变带来更多麻烦!
掌握好三种传值方式作为基础,更深一步探索递归以及其他复杂算法,结合自定义函数,写出更完美代码!
1、函数在定义前必须生命函数的类型,既为返回值类型+函数名+(形参)+";"。
()内作用是为代表其内为啥类型的数据,实参变量必须为确定值,形参在定义函数中代替实参位置,为一般变量使用,形参和实参类型必须相同。
2、参数传递分为
①按值传递
②指针地址传递
③引用传递
①:
实参和形参之间互不影响,当函数运行结束后,形参的内存空间被释放,同时函数返回值(如果有的话),以此发挥作用。
②:
即为将形参定义为指针变量,实参即为地址,和①不同的是实参将储存地址传递给形参,实参和形参的指针都指向一个地址,形参地址中内容改变时实参也改变。
指针变量定义为类型标识符+"*"+变量名,"&"+变量名为取地址运算,"*"+指针变量为取内容运算。
当把数组名赋值给指针变量,数组名为起始地址,int *p=a,int *p=&a[0],都为赋初值。
p+1指向下一个元素而不是下一个字。*(p+1)=2即为a[1]=2。
a+i表示a[i]地址&a[i].
因此*(a+i)=a[i].
可以用指针传递不确定个数的数组.
指针传递可得到多个变化的值。
实参指针调用前必须赋值。
③:
变量类型&引用名=变量名。
int &b=a;(b为a别名)。
对b改变即为对a改变。
引用名为变量的别名,不会被分配空间。
引用名只能对应一个变量名。
传引用更容易阅读,改变形参时同时改变实参。
用一个代码解释上三种传递方式:
#include<iostream>
using namespace std;
void swap1(int a, int b) { //按值传递
int tmp = a;
a = b;
b = tmp;
}
void swap2(int* a, int* b) {//传递指针
int tmp = *a;
*a = *b;
*b = tmp;
}
void swap3(int& a, int& b) {//传递引用
int tmp = a;
a = b;
b = tmp;
}
int main() {
int a = 1; int b = 2;
swap1(a, b);
printf("a=%d b=%d \n", a, b); //a=1,b =2
int c = 1; int d = 2;
swap2(&c, &d);
printf("c=%d d=%d \n", c, d); //a=2,b=1
int e = 1; int f = 2;
swap3(e, f);
printf("e=%d f=%d \n", e, f); //e=2,f=1
}
用指针输出数组:
int main( )
{ int a[10], i;
int *p;
for (i=0; i<10; i++)
cin>>a[i];
for (p=a; p<a+10; p++)
cout<<*p<<‘\t’;
}
或
int main( )
{ int a[10], i;
int *p=a;
for (i=0; i<10; i++)
cin>>a[i];
for (i=0; i<10; i++)
cout<<*p++<<‘\t’;
}
二、(题型)
题型主要为调用一次函数
例如:求10的阶乘
#include<iostream>
using namespace std;
int js(int);
int main()
{
int sum=0;
for(int i=1;i<=10;++i)
sum+=js(i);
cout<<"sum="<<sum<<endl;
return 0;
}
int js(int n)
{
int s=1;
for(int i=1;i<=n;++i)
s*=i;
return s;
}
定义函数中调用定义函数
例如:
求俩数最小公倍数
#include<iostream>
using namespace std;
int x,y;
int gcd(int x,int y)
{
int r=x%y;
while(r)
{
x=y;
y=r;
r=x%y;
}
return y;
}
int lcm()
{
return x*y/gcd(x,y);
}
int main()
{
cin>>x>>y;
cout<<lcm()<<endl;
return 0;
}
//上述函数中x,y用全局变量,因此变量值共享,但同时亦有副作用,使用过多会增加调试困难。
同时有递归函数等,即函数自己调用其自身,使n不断减小直到可直接得出结果后,再回溯
得出最终结果。
例如:
求 x的n次方的值
#include<iostream>
using namespace std;
int xn(int);
int x;
int main()
{
int n;
cin>>x>>n;
cout<<xn(n)<<endl;
return 0;
}
int xn(int n)
{
if(n==0)return 1;
else return x*xn(n-1);
}
除以上题型外,函数还会结合其他算法的题型等。
三、(感悟)
按值传递易理解但形参与实参无关,形参不对实参有影响,地址传递虽可以,但形式复杂不易阅读,且易产生错误,而引用完美解决了上述两个问题。
全局变量在简单自定义函数中虽好用,但在复杂情况下,应适当使用,防止因变量值的改变带来更多麻烦!
掌握好三种传值方式作为基础,更深一步探索递归以及其他复杂算法,结合自定义函数,写出更完美代码!