第6周

6.1 函数

定义:

  返回值类型 函数名(参数1类型 参数1名称,参数2类型 参数2名称...)

  {

      语句组(即“函数体”)

  }

调用函数:函数名 (参数1,参数2...)。对函数的调用,也是一个表达式,其值由函数内部的return语句决定。

return语句的功能是结束函数的执行,并将返回值作为结果返回。返回值是常量、变量或复杂的表达式均可。如果返回值类型为void,则可以直接写return ;。

return语句作为函数的出口,可以在函数中多次出现。多个return语句的返回值可以不同。在哪个return语句结束函数的执行,返回值就和该return语句里的返回值相等。

函数的调用语句前有函数的声明即可:返回值类型 函数名(参数1类型 参数1名称,参数2类型,参数2名称...),其中参数名称可以省略。函数声明也称为“函数原型”。

eg. int Max(int a, int b);  double Sqrt(double);  double Distance(double, double, double, double);

函数的形参是实参的一个拷贝,且形参的改变不会影响到实参(形参类型为数组、引用或对象时除外)。

一维数组作为形参时的写法:类型名 数组名[]。不用写出元素的个数,eg. void PrintArray(int a[], int length){}。

二维数组作为形参时,必须写明列数,不用写明行数(写明列数编译器才能根据下标算出元素的地址)。

6.2 库函数和头文件

库函数:编译器自带的函数。头文件内部包含许多库函数的声明以及其他信息。

6.3 递归初步

一个函数自己调用自己,就是递归。递归函数需要有终止条件,否则就会导致无穷递归。eg. 阶乘,斐波拉契数列。

6.4 位运算

用于对整数类型(int, char, long等)变量中的某一位(bit)或者若干位进行操作。

六种位运算符:&  |  ^  ~  <<  >>

&:通常用来将某变量中的某些位置0且同时保留其它位不变,也可以用来获取变量中的某一位。

|:通常用来将某变量中的某些位置1且同时保留其它位不变。

^:通常用来将某变量中的某些位取反,且保留其它位不变。特点:若a^b = c,则c^b = a,c^a = b,可用于简单加密与解密。还能不通过临时变量交换两个变量的值。

  eg. int a = 5, b = 7;  a = a^b;  b = b^a;  a = a^b;  即可实现a,b值的交换。

~:单目运算符。

<<:a << b,将a各二进位全部左移b位后得到的值。左移时,高位丢弃,低位补0,a的值不因运算而改变。实际上,左移1位相当于乘以2,左移操作比乘法操作快很多。

>>:a >> b,将a各二进位全部右移b位后得到的值。右移时,移出最右边的位被丢弃,a的值不改变。右移一位相当于除以2,并将结果往小里取整。

  对于有符号数(char, int, long等),右移时符号位(即最高位)将一起移动。原符号位为1,高位就补充1;为0时同理。

 

作业

1.Pell数列

Description:Pell数列a1, a2, a3, ...的定义是这样的,a1 = 1, a2 = 2, ... , an = 2 * an − 1 + an - 2 (n > 2)。给出一个正整数k,要求Pell数列的第k项模上32767是多少。

Input:第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数k (1 ≤ k < 1000000)。

Output:n行,每行输出对应一个输入。输出应是一个非负整数。

Sample Input:

2

1

8

Sample Output:

1

408

 1 #include <cstdio>
 2 
 3 #define maxn 1000000
 4 int arr[maxn+10];
 5 
 6 int main()
 7 {
 8     //freopen("D:\\temp\\test\\tmp.txt", "r", stdin);
 9 
10     arr[1] = 1;
11     arr[2] = 2;
12     for(int i=3; i<=maxn; i++)
13         arr[i] = (2*arr[i-1]+arr[i-2])%32767;
14 
15     int n;
16     scanf("%d", &n);
17     for(int i=0; i<n; i++) {
18         int tmp;
19         scanf("%d", &tmp);
20         printf("%d\n", arr[tmp]);
21     }
22 
23     return 0;
24 }

2.求最大公约数问题

Description:给定两个正整数,求它们的最大公约数。

Input:输入一行,包含两个正整数(<1,000,000,000)。

Output:输出一个正整数,即这两个正整数的最大公约数。

Sample Input:6 9

Sample Output:3

 1 #include <cstdio>
 2 
 3 int gcd(int a, int b)
 4 {
 5     if(a%b == 0)
 6         return b;
 7     return gcd(b, a%b);
 8 }
 9 
10 int main()
11 {
12     //freopen("D:\\temp\\test\\tmp.txt", "r", stdin);
13 
14     int a, b;
15     scanf("%d %d", &a, &b);
16 
17     printf("%d\n", gcd(a, b));
18 
19     return 0;
20 }

3.填空:第i位替换

Description:写出函数中缺失的部分,使得函数返回值为一个整数,该整数的第i位和m的第i位相同,其他位和n相同。请使用【一行代码】补全bitManipulation1函数。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int bitManipulation1(int n, int m, int i) {
 5 // Your Code Here
 6 }
 7 
 8 int main() {
 9     int n, m, i, t;
10     cin >> t;
11     while (t--) { 
12         cin >> n >> m >> i;
13         cout << bitManipulation1(n, m, i) << endl;
14     }
15     return 0;
16 }

Input:第一行是整数 t,表示测试组数。每组测试数据包含一行,是三个整数 n, m 和 i (0<=i<=31)。

Output:对每组输入数据,每行输出整型变量n变化后的结果。

Sample Input:

1

1 2 1

Sample Output:3

return (n&(~(1<<i)) | ((m >> i)&1)<< i);

4.填空:第i位取反

Description:写出函数中缺失的部分,使得函数返回值为一个整数,该整数的第i位是n的第i位取反,其余位和n相同。请使用【一行代码】补全bitManipulation2函数。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int bitManipulation2(int n, int i) {
 5 // Your Code Here
 6 }
 7 
 8 int main() {
 9     int t, n, i;
10     cin >> t;
11     while (t--) {
12         cin >> n >> i;
13         cout << bitManipulation2(n, i) << endl;
14     }
15     return 0;
16 }

Input:第一行是整数 t,表示测试组数。每组测试数据包含一行,是两个整数 n 和 i (0<=i<=31)。

Output:输出整型变量n中的第i位取反的结果。

Sample Input:

1

1 0

Sample Output:0

return n^(1<<i);

5.填空:左边i位取反

Description:写出函数中缺失的部分,使得函数返回值为一个整数,该整数的左边i位是n的左边i位取反,其余位和n相同。请使用【一行代码】补全bitManipulation3函数。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int bitManipulation3(int n, int i) {
 5 // Your Code Here
 6 }
 7 
 8 int main() {
 9     int t, n, i;
10     cin >> t;
11     while (t--) {
12         cin >> n >> i;
13         cout << bitManipulation3(n, i) << endl;
14     }
15     return 0;
16 }

Input:第一行是整数 t,表示测试组数。每组测试数据包含一行,是两个整数 n 和 i (1<=i<=32)。

Output:对每组输入数据,输出整型变量n中左边i位取反的结果。

Sample Input:

1

0 32

Sample Output:-1

return n ^ (~0<<(32-i));

6.计算整数k

Description:

输入整数 n ( 0 <=n<= 2^30) , 以及整数i,j(0 <= i,j <31,i < j-1), 输出整数k(按十六进制输出结果 ),k的第i位和n相同,第j位和n不同,i,j之间的位是1, 其他位都是0。

这里提到的所有的位,指的都是二进制位,最右边算第0位。

Input:第一行是整数 t,表示数据组数。每组输入数据是一行,三个整数 n,i和j。

Output:对每组输入数据,按十六进制输出结果。

Sample Input:

2

23 3 5

7 0 2

Sample Output:

30

3

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <list>
 5 
 6 using namespace std;
 7 
 8 void SetBit(int & n,int i,int v)
 9 {
10     if(v)
11         n |= (1<<i);
12     else
13         n &= ~(1<<i);
14 }
15 
16 int GetBit(int n, int i)
17 {
18     return (n>>i) & 1;
19 }
20 
21 int main()
22 {
23     //freopen("D:\\temp\\test\\tmp.txt", "r", stdin);
24 
25     int n,i,j;
26     int t;
27     cin >> t;
28 
29     while(t--) {
30         cin >> n >> i >> j;
31         int tmp = (0xffffffff<<i)&(0xffffffff>>(31-j));
32         SetBit(tmp, i, GetBit(n,i));
33         if(GetBit(n,j))
34             SetBit(tmp, j, 0);
35         else
36             SetBit(tmp, j, 1);
37         cout << hex << tmp << endl;
38     }
39 
40     return 0;
41 }

 

posted @ 2016-07-13 17:52  VincentValentine  阅读(984)  评论(0编辑  收藏  举报