文章目录:
8.1 函数简介
1)函数可以实现将某个功能的代码保险行起来,调用的时候只需一条语句,就可以使用该功能.
2)函数的定义如下
返回值类型 函数名(参数1类型 参数1名称, 参数2类型 参数2名称......){
函数体;
}
3)如果不需要返回值,则返回值类型可以写void.
4)调用函数
函数名(参数1,参数2......);
5)对函数的调用也是一个表达式,函数调用表达式的值由函数内部的return语句决定
6)return语法如下:
return 返回值;
7)如果返回类型为void 则直接写return
return;
8)return语句的功能是结束函数执行并将返回值作为结果返回.返回值是常量、变量、表达式都可以.
9)return语句作为函数的出口,可以再函数中多次出现,多个return语句的返回值可以不同.在哪个return语句结束函数执行就返回哪个返回值.
函数使用示例1:MAX函数.
#include <iostream>
using namespace std;
int Max(int x, int y){ //求两个整型变量的最大值 括号里的x和y为形参
if (x > y)
return x;
return y;
}
int main(){
int n = Max(4,6); //括号里的4和6位实参
cout << n << "," << Max(20,n) << endl; //20和n为实参
return 0;
}
输出:6,20
函数使用示例2:判断一个数是否为素数.
#include <iostream>
using namespace std;
bool IsPrime(unsigned int n){
if( n <= 1)
return false;
for ( int i = 2; i < n; i++){
if ( n % i == 0)
return false;
}
return true;
}
int main(){
cout << IsPrime(3) << " " << IsPrime(8) << " " <<IsPrime(36) << endl;
return 0;
}
输出:1 0 0
函数使用示例3:已知三角形三个顶点位置,求边长.
#include <iostream>
using namespace std;
#define EPS 0.001 //用来控制精度
double Sqrt(double a){
double x = a / 2, lastX = x + 1 + EPS;
while ( x - lastX > EPS || lastX - x > EPS){
lastX = x;
x = ( x + a / x) / 2;
}
return x;
}
//求距离函数
double Distance(double x1, double y1, double x2, double y2){
return Sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
}
int main(){
int x1,y1,x2,y2,x3,y3;
cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
cout << Distance(x1,y1,x2,y2) << endl;
cout << Distance(x1,y1,x3,y3) << endl;
cout << Distance(x2,y2,x3,y3) << endl;
return 0;
}
8.2 函数的声明与调用
1)一般来说函数的定义必须出现在函数调用语句之前,否则调用语句编译出错
2)函数调用语句前面有函数的声明即可,不一定要有定义.
3)函数声明形式如下:
返回值类型 函数名(参数1类型 参数1名称,参数2类型 参数2名称.....)
int Max(int a, int b);
4)函数声明参数名称可以省略,函数声明也称“函数的原型”.
double Distance(double, double,double,double);
5)如果函数A调用了函数B,函数B也调用了A,这样写
void B(); //声明
void A(){
B();
return;
}
void B(){
A();
return;
}
6)C/C++程序从main函数开始执行,执行到main的return结束.
7)函数的形参是实参的一个拷贝,且形参改变不会印象到实参(数组和引用除外).
#include <iostream>
using namespace std;
void Swap( int a, int b){
int temp = a;
a = b;
b = temp;
cout << "交换后: a = " << a <<" b = " << b <<endl;
}
int main(){
int a = 5, b = 4;
Swap(a,b);
cout << "交换后: a = " << a <<" b = " << b <<endl;
return 0;
}
8.3 数组作为函数的参数
8.3.1 一维数组作为函数的参数
1)一维数组作为形参时的写法如下:
类型名 数组名[]
2)不用写出数组的元素个数.
void PrintArrray(int a[]){}
3)数组作为函数形参时,是传引用的,即形参数组改变了实参数组也会改变.
例题1;编写一个球整形数组最大值得函数
#include <iostream>
using namespace std;
int a1[4] = {4,5,1,3};
int a2[] = {5,7,4,6};
int FindMax(int a[], int length){ //length是数组的长度
int mx = a[0];
for (int i = 1; i < length; i++){
if (a[i] > mx)
mx = a[i];
}
return mx;
}
int main(){
cout << FindMax(a1, sizeof(a1) / sizeof(int)) <<endl;
cout << FindMax(a2, sizeof(a2) / sizeof(int)) <<endl;
return 0;
}
输出:5 7
例题2:编写一个把数组所有元素置为0的函数.
#include <iostream>
using namespace std;
int a1[4] = {4,5,1,3};
int a2[] = {5,7,4,6};
void SetZero(int a[], int length){ //length是数组的长度
for (int i = 0; i < length; i++){
a[i] = 0;
}
}
int main(){
SetZero(a1,4);
for (int i = 0; i < 4; i++){
cout << a1[i] << " ";
}
return 0;
}
输出:0 0 0 0
8.3.2 二维数组作为函数的参数
1)二维数组作为函数的形参时,必须写明有多少列,不用写多少行.
int a[][5];
2)必须要写明列数,编译器才能根据下标算出元素的地址.
3)a[i][j]的地址为:
数组首地址 + i * N * sizeof(a[0][0])) + j * sizeof(a[0][0])) ;
8.4 库函数和头文件
**1)库函数:C/C++标准规定的,编译器自带的函数.
2)头文件:C++编译器提供许多头文件:iostream、cmath、string等
3)头文件内部包含许多库函数的声明及其他信息,如cin、cout的定义.
4)可将头文件包含到程序中,伺候即可使用头文件中定义的库函数及其他信息.**5)
#include < iostream >
#include < cmath >
#include < string >
5 )cmath包含的库函数声明有:
6)字符处理函数:
8.5 递归初步
1)一个函数自己调用自己就是递归.
2)递归需要有终止条件,否则会无穷递归导致程序崩溃.
例题:返回n的阶乘.
例题:求斐波那契数列第n项
#include <iostream>
using namespace std;
int Fib(int n){
if ( n == 1 || n == 2){
return 1;
}
return Fib(n-1) + Fib(n-2);
}
int main(){
cout << Fib(5) << endl;
return 0;
}
输出:5
8.6 位运算
1)用于对于整数类型变量中的某一位(bit)或者若干位进行操作,8位为一个字节.
例如:
(1)判断某一位是否为1
(2)只改变其中某一位,保持其他位都不变.
2)C/C++一共提供六种位运算符来进行位运算操作:
(1)& 按位与(双目)
(2)| 按位或(双目)
(3)^ 按位异或(双目)
(4)~ 按位非(取反)(单目)
(5)<< 左移(双目)
(6)>> 右移(双目)
3)按位与"&":将参与运算的两个操作数各对应的二进制位进行与操作,只有两个对应的二进制位均为1时,结果的对应二进制位才为1,否则为0.
例如:表达式"21 & 18"的计算结果为16:
21的二进制表示:0000 0000 0000 0000 0000 0000 0001 0101
18的二进制表示:0000 0000 0000 0000 0000 0000 0001 0010
结果二进制表示:0000 0000 0000 0000 0000 0000 0001 0000
4)通常用来将某变量的某些位清0且保持其他位不变,也可以用来获取变量中的某一位.
例如:将int型的变量n的低8位全部置0而其余位不变.
n = n & 0xffffff00;
n &= 0xffffff00;
如果n是short类型的:
n &= 0xff00;
例题:如何判断一个int型变量的第7位是否为1(从右往左,从0开始数):
n & 0x80 == 0x80; //是否为真
0x80:1000 0000
4)按位或"|":将参与运算的两个操作数各对应的二进制位进行与操作,只要两个对应的二进制位有一个为1时,结果的对应二进制位就为1,否则为0.
例题:表达式"21 | 18"的值为23:
21的二进制表示:0000 0000 0000 0000 0000 0000 0001 0101
18的二进制表示:0000 0000 0000 0000 0000 0000 0001 0010
结果二进制表示:0000 0000 0000 0000 0000 0000 0001 0110
5)按位或运算通常用来将某些变量中的某些位置1且保留其他位不变.
例如:将int型的变量n的低8位全部置1而其余位不变.
n |= 0xff;
0xff:1111 1111
6)按位异或"^":将参与运算的两个操作数各对应的二进制位进行与操作,只要两个对应的二进制位不相同时,结果的对应二进制位就为1,否则为0.
例题:表达式"21 | 18"的值为23:
21的二进制表示:0000 0000 0000 0000 0000 0000 0001 0101
18的二进制表示:0000 0000 0000 0000 0000 0000 0001 0010
结果二进制表示:0000 0000 0000 0000 0000 0000 0000 0111
7)按位异或通常用来将某些变量中的某些位取反且其他位保持不变.
例如:将int型的变量n的低8位全部取反而其余位不变.
n ^= 0xff;
0xff:1111 1111
8)按位异或的性质:如果a^b = c,那么就有c^a = b以及c^b = a.
9)按位异或还可以实现不通过临时变量就能交换两个变量的值.
int a = 5, b = 7;
a = a ^ b;
b = b ^ a;
a = a ^ b;
10)按位非"~":就是将对应二进制位取反.
例题:~21为0xffffffea
21的二进制表示: 0000 0000 0000 0000 0000 0000 0001 0101
~21的二进制表示:1111 1111 1111 1111 1111 1111 1110 1010
11)左移运算符"<<"
表达式:a << b的值为将a的二进制位全部左移b位后得到的值,左移时高位丢弃低位补0
例题:9 << 4的值为144
9的二进制:0000 0000 0000 0000 0000 0000 0000 1001
左移4位后:0000 0000 0000 0000 0000 0000 1001 0000
12)实际上,左移一位就相当于乘以2,左移n为就相当于乘以2的n次方,左移操作要比乘法快很多.
13)右移运算符">>"
表达式:a >> b的值为将a的二进制位全部右移b位后得到的值,移出最右边的位被丢弃.
14)对于有符号数(int、long…),在右移时符号位将一起移动,并且大多数C/C++编译器规定,如果原符号位为1则右移时最高位就补充1,原符号位为0则右移时最高位就补充0.
15)实际上,右移n为就相当于除以2的n次方,并将结果往小里取整.
-25 >> 4 = -2; //-25/16 = -1.56 => -2
-2 >> 4 = -1; //-2/4 = -0.5 => -1
18 >> 4 = 1; //18/16 = 1.125 => 1
例题:有两个整型变量a和n(0 <= n <= 31),要求写一个表达式,使表达式的值和a的第n位相同
答案1:(a >> n) & 1;
答案2:(a & (1 << n)) >> n;