810 likes | 1.02k Views
第十一讲: 函数及其应用. 北京大学 信息科学技术学院 20 13 年 1 2 月. 一种常见的程序行为. 什么原因?. 原因之一. #include < stdio.h > int main(){ int n; scanf (“%d”, n ); printf(“%d”, n); return 0; }. scanf 函数中的 变量前面没有 &. 原因之二. #include < stdio.h > int main(){ int n; scanf (“ %lf ”, &n); printf(“%d”, n);
E N D
第十一讲:函数及其应用 北京大学信息科学技术学院 2013年12月
原因之一 #include <stdio.h> int main(){ int n; scanf(“%d”, n); printf(“%d”, n); return 0; } scanf函数中的 变量前面没有&
原因之二 #include <stdio.h> int main(){ int n; scanf(“%lf”, &n); printf(“%d”, n); return 0; } scanf函数中,使用了 错误的变量修饰符
原因之三 #include <stdio.h> int main(){ int data[10]; scanf(“%d”, &(data[10])); printf(“%d”, data[0]); return 0; } 数组访问越界
原因之四 程序占用了 过多的内存空间 #include <stdio.h> int main(){ int data[1000000]; scanf(“%d”, &(data[0])); printf(“%d”, data[0]); return 0; }
C程序基本框架 一个C程序由一组函数组成 一个C程序由一个主函数(main) 和若干自定义函数(可选) 组成 一个C程序必须且只能有一个 main函数
C程序的基本框架 预编译声明(宏定义、头文件) 自定义函数的声明 int main( ) { … … return 0; } 主函数的定义 自定义函数的定义
三类函数及其调用关系 主函数main() 自定义函数 如何自己定义一个函数? 标准库函数
如何自己定义一个函数? 预编译声明(宏定义、头文件) ? 自定义函数的声明 int main( ) { … … return 0; } 主函数的定义 ? 自定义函数的定义
如何自己定义一个函数? 预编译声明(宏定义、头文件) ? 自定义函数的声明 返回值类型函数名(参数); int main( ) { … … return 0; } 返回值类型函数名(参数){ … … return 一个返回值; } 主函数的定义 ? 自定义函数的定义
自定义函数示例 #include <stdio.h> int main(){ int a, b, c; scanf(“%d%d”, &a, &b); c = a+b; printf(“%d\n”, c); return 0; } #include <stdio.h> int add(int x, int y); int main(){ int a, b, c; scanf(“%d%d”, &a, &b); c = add(a, b); printf(“%d\n”, c); return 0; } int add(int x, int y){ int result; result = x+y; return result; } “两个整数相加”函数 的声明 在主程序中调用 “两个整数相加”函数 如何把 “两个整数相加”的功能 封装在一个函数中? “两个整数相加”函数 的定义
请一位同学上台, 编写一个计算圆的面积的函数; 圆面积的计算公式: area(r) = PI * r * r
#include <stdio.h> int main( ){ return 0; } double area(double r){ double s; s = 3.1415926 * r * r; return s; } 请一位同学上台, 编写一个程序; 要求: 1. 接收用户输入的一个浮点数; 2. 计算以该浮点数为半径的 圆的面积; 3. 调用area函数; 4. 输出计算结果;
#include <stdio.h> double area(double r); int main(){ double bj, mj; scanf("%lf", &bj); mj = area(bj); printf("%lf\n", mj); return 0; } double area(double r){ double s; s = 3.1415926 * r * r; return s; } 函数声明 函数调用 函数的返回值 被赋给了 mj 函数定义
n < 100 与7无关的正整数: 1. 不能被7整除,并且 2. 其十进制表示法中任一位数中都没有数字7
#include <stdio.h> int main(){ int num, result = 0; scanf("%d", &num); for(int i = 1; i <= num; i++){ if( ){ result += i*i; } } printf("%d", result); return 0; } int yu7WuGuan(int number); yu7WuGuan(i)
与7无关的正整数: 1. 不能被7整除,并且 2. 其十进制表示法中任一位数中都没有数字7 n < 100 int yu7WuGuan(int number){ if(i%7 == 0){ return 0;} if(i==7 || i==17 || i== 27 || i== 37 || i== 47 || i== 57 || i== 67 || i== 77 || i== 87 || i== 97 || i== 71 || i== 72 || i== 73 || i== 74 || i== 75 || i== 76 || i== 78 || i== 79){ return 0;} return 1; } 穷举法
n < 100 如果对n的大小没有限制呢?
#include <stdio.h> int main(){ int num, result = 0; scanf("%d", &num); for(int i = 1; i <= num; i++){ if( ){ result += i*i; } } printf("%d", result); return 0; } int yu7WuGuan(int number); yu7WuGuan(i)
int yu7WuGuan(int number){ if(number%7 == 0){ return 0; } for(int num = number;num > 0;num /= 10){ if (num%10 == 7){ return 0; } } return 1; }
什么是闰年? 闰年的充分必要条件是: “年份能被400整除” 或者 “年份能被4整除,但不能被100整除”
判断某一年份是否是闰年 #include <stdio.h> int main(){ int year; scanf(“%d”, &year); if( ){ printf(“%d is RuiNian.”, year); } else{ printf(“%d not RuiNian.”, year); } return 0; } int isRunNian(int year); isRunNian(year)
判断闰年函数的定义 int isRunNian(int year){ int result; if(year%400 == 0||(year%4==0 && year%100!=0)){ result = 1; } else{ result = 0; } return result; }
问题2:给定一个年月日,判断这一天是这一年的第几天问题2:给定一个年月日,判断这一天是这一年的第几天
判断一个年月日是所在年的第几天 #include <stdio.h> int main(){ int y, m, d, result; scanf(“%d%d%d”, &y, &m, &d); result = ; printf(“%d”, result); return 0; } int DiJiTian(int year, int month, int day); DiJiTian(y, m, d)
第几天函数求解思路 (某年,1月,1日) (某年,某月,某日) a 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 b c
第几天函数定义 int DiJiTian(int year, int month, int day){ int result = 0; return result; } 请一位同学上台, 把这个函数填充完整。
第几天函数定义 int DiJiTian(int year, int month, int day){ int result = 0; for(int i = 1; i < month; i++){ if(i==1||i==3||i==5||i==7||i==8||i==10||i==12){ result += 31; } else if (i == 4 || i ==6 || i == 9 || i==11){ result += 30; } else if(i == 2){ if(isRunNian(year)){ result += 29; } else { result += 28; } } } result += day; return result; }
问题3:输入两个日期(年月日)求两个日期之间相隔的天数问题3:输入两个日期(年月日)求两个日期之间相隔的天数
输入输出示例 输入 输出 1978 10 1 1978 10 1 0 1978 10 1 1978 10 2 1 1978 10 2 1978 10 1 1 2001 1 1 2000 1 1 366 2000 1 1 2002 1 1 731 注意:1. 输入的日期没有固定的次序关系; 2. 两个日期不一定是在同一年; 3. 必须考虑闰年的因素。
可以利用的两个函数 • 判断闰年的函数 • int isRunNian(int year); • 求解某一日期是当年的第几天的函数 • int DiJiTian(int year, int month, intday);
建立程序框架 #include <stdio.h> int DiJiTian(int year, int month, int day); int isRunNian(int year); int main(){ inty1, m1, d1; inty2, m2, d2; int result = 0; scanf("%d %d %d", &y1, &m1, &d1); scanf("%d %d %d", &y2, &m2, &d2); printf("%d\n", result); return 0; } int xgts(int y1, int m1, int d1, int y2, int m2, int d2); xgts(y1, m1, d1, y2, m2, d2); result =
相隔天数函数定义 int xgts(int y1, int m1, int d1, int y2, int m2, int d2){ int result; return result; } 待填写区域
问题分析 k年 k+1年 k+2年 k+n年 k+n+1年 … … 这两种情况 有什么区别? 日期1 日期1 Case 2 日期2 日期2 k年 k+1年 k+2年 k+n年 k+n+1年 … … Case 1
问题分析 分两种情况考虑: 情况1: 当两个日期在同一年; 情况2: 当两个日期不在同一年;
相隔天数函数定义 int xgts(int y1, int m1, int d1, int y2, int m2, int d2){ int result; return result; } if(y1 == y2){ … //情况1的代码 }else{ … //情况2的代码 }
情况1:当两个日期在同一年 b k年 a result 日期1 日期2
情况1:当两个日期在同一年 //情况1的代码 result = DiJiTian(y1, m1, d1) - DiJiTian(y2, m2, d2); if(result < 0){ result = 0 - result; } 请一位同学在黑板上写下: 情况1对应的代码
情况2:当两个日期不在同一年 a b c k年 k+1年 k+2年 k+n年 k+n+1年 … … result 日期1 日期2 result = a + b + c
情况2:当两个日期不在同一年 //情况2的代码 if(year1 > year2){ //交换 y1, y2 的值; //交换 m1, m2的值; //交换 d1, d2的值; } int a, b, c; //计算a的代码 //计算b的代码 //计算c的代码 result = a + b + c;
情况2:当两个日期不在同一年 //计算c的代码 c = DiJiTian(y2, m2, d2);
情况2:当两个日期不在同一年 //计算a的代码 if(isRunNian(y1)){ a = 366 - DiJiTian(y1, m1, d1); }else{ a = 365 - DiJiTian(y1, m1, d1); }
情况2:当两个日期不在同一年 b = 0; for(inti = y1 + 1; i < y2; i++){ if(isRunNian(i)){ b += 366; }else{ b += 365; } } //计算b的代码
平方根函数 这个函数是 怎么实现的呢? C标准库函数 sqrt: doublesqrt(double x); 注意#include <math.h>