C程序中的函数(Week 1&2)

函数

函数的定义

  • 对函数的普遍认识:y=f(x)

  • C语言中的常用函数

    • 平方根: r = sqrt(100.0)
    • 底数x的y次幂:k = pow(x,y)
    • 字符串的长度:i = strlen(str1)
    • 比较两个字符串的大小: v = strcmp(str1,str2)
    • 把字符串转换为相应整数: n = atoi(str1)
  • 在C语言中,我们可以把所有程序都组织成函数

  • 定义一个函数:

  1. int absolute(int n)//n为形式参数,用于辅助进行函数定义,与实际参数相对
  2. {
  3. if(n<0)
  4. return (-n);
  5. else
  6. return n;
  7. }
  8. float max(float a, float b)//2个形式参数的情况
  9. {
  10. if(a > b)
  11. return a;
  12. else
  13. retuen b;
  14. }
  15. int get_int() //无参函数的例子
  16. {
  17. int n = 0;
  18. cout<<"Please input an integer:"<<endl;
  19. cin >> n;
  20. return n;
  21. }
  22. void delay(int n) //无返回值函数的例子
  23. {
  24. for(int i = 0; i < n* 100000;i++);
  25. return; //可不写
  26. }
  27. void show() //既无参数也无返回值的例子
  28. {
  29. cout<<"***************************************";
  30. cout<<"********************show***************";
  31. cout<<"***************************************";
  32. }
  33. #include <iostream>
  34. using namespace std;
  35. int main() //程序执行的入口
  36. {
  37. return 0;
  38. }
  39. //用void定义的main函数是老的C标准,因为无法获知调用结果所以该方式被放弃
  • 函数调用的方式

    • 作为独立语句
    • 作为表达式的一部分(存在一个计算式中)
    • 实际参数形式出现在其他函数的调用
  • 函数是C程序的基本构成单位

    • 一个C程序由一个或多个源文件组成
    • 一个源程序文件可以由一个或多个函数组成
  • 函数的类型——函数的返回值的数据类型

  • 可以在main函数的后面定义函数,但必须要在main函数前面先声明

  • 函数原型&函数声明

    • 函数原型

      • 由函数的返回类型、函数名以及参数表构成的一个符号串,其中参数可不写名字

        bool checkPrime(int)

      • 函数的原型也叫函数的"Signature"

    • 函数声明

      • 函数在使用前都要声明,除非被调用函数的定义部分已经出现在主调函数之前
      • 在C语言中,函数声明=函数原型

函数的执行

  • 在main函数中调用max函数的过程

    • 在调用max函数之前

      • 初始化max()
      • 传递参数
      • 保存当前现场
    • 在调用max函数之后
      • 接受函数的返回值
      • 恢复现场,从断点处继续执行
  • 函数参数的传递
    • 实参把数据"copy"给形参,因此对实参本身无影响
    • 实惨与形参具有不同的存储单元,实参与形参变量的数据传递是"值传递"
    • 函数调用时,系统给形参分配存储单元,并将实参的传给形参
      • 实参与形参的类型必须相同可以兼容
  • 思考总结
    • 值传递!值传递!值传递!

变量的作用范围

  • 变量的分类

    • 局部变量:在函数内或代码块内定义,其作用域是函数内或代码块内
    • 全局变量:所有函数外定义的变量,其作用域是从定义变量的位置开始到程序文件结束为止
  • 当全局变量与局部变量同名时,局部变量将在自己的作用域内有效,它将屏蔽同名的全局变量。

数组与函数

  • 数组元素做函数参数,没有什么特别(值传递

  • 数组名做函数参数

    • 虽然仍是copy,但数组名不是变量,而是数组在内存中的地址,因此不是值传递
  • 总结

    • 传递地址是一件严重的事情

函数举例

例1 日历问题

  • 问题:给定从公元2000年1月1日开始逝去的天数,请编写程序给出这一天是哪年哪月哪日星期几

    • 注意闰年:闰年被定义为能被4整除的年份,但能被100整除而不能被400整除的年不是闰年
    • 注意每个月的天数是不同的
  • 输入输出要求
    • 输入多组数据,每组一个正整数,表示从2000年1月1日开始已经过去的天数
    • 对输入的每一个天数,输出一行,该行包含对应的日期和星期几,格式为"YYYY-MM-DD DayOfWeek"
    • 其中"DayOfWeek"必须是:Sunday,Monday,Tuesday,WWednesday,Thursday,Friday and Saturday.
    • 输入最后一行是-1,不必处理,可以假设结果的年份不会超过9999
  • 思路
    • 先记录days,再计算出星期几,再减掉每年的天数(还要判断年是不是闰年),再减掉每月的天数(每月天数是不同的),从而逐步得到最终结果。
  1. //主程序
  2. #include<iostream>
  3. using namespace std;
  4. int days;
  5. int get_dayofweek();
  6. int get_year();
  7. int get_month(int);
  8. int main()
  9. {
  10. int year,month,dayofweek;
  11. int leap_year;
  12. char week[7][10] = {"Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"};
  13. while((cin>>days) && days!= -1)
  14. {
  15. dayofweek = get_dayofweek();
  16. year = get_year();
  17. leap_year = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
  18. month = get_month(leap_year);
  19. cout<<year<<"-"<<month<<"-"<<++days<<" "<<week[dayofweek];
  20. }
  21. return 0;
  22. }
  23. //计算星期几,2000年1月1日是周六
  24. int get_dayofweek()
  25. {
  26. return days % 7;
  27. }
  28. //计算年数
  29. int get_year()
  30. {
  31. int i = 2000, leap_year;
  32. while(1)
  33. {
  34. leap_year = (i % 4 == 0 && i % 100 != 0 || i % 400 == 0);
  35. if(leap_year == 1 && days >=366)
  36. {
  37. days = days - 366;
  38. i++;
  39. continue;
  40. }
  41. else if(leap_year == 0 && days >= 365)
  42. {
  43. days = days - 365;
  44. i++;
  45. continue;
  46. }
  47. else break;
  48. }
  49. return i;
  50. }
  51. //计算月份
  52. int get_month(int leap_year)
  53. {
  54. int pmonth[12] = {31,28,31,30,31,30,31,31,30,31,30,31}
  55. int rmonth[12] = {31,29,31,30,31,30,31,31,30,31,30,31}
  56. int j = 0;
  57. while(1)
  58. {
  59. if(leap_year == 1 && days >= rmonth[j])
  60. {
  61. days = days - rmonth[j];
  62. j++;
  63. }
  64. else if(leap_year == 0 && days >= pmonth[j])
  65. {
  66. days = days - pmonth[j];
  67. j++;
  68. }
  69. else break;
  70. }
  71. return ++j
  72. }
  73. //在该程序中,定义了全局变量days
  74. //该变量在三个函数和主函数中都要使用,会带来一些问题:围绕着days的错误会影响所有函数
  75. //

总结

  • 全局变量

    • 破坏了函数的相对独立性
    • 增加了函数之间的耦合性
    • 函数之间的交互不够清晰
  • 因此
    • 在不是非常必要的情况下,不要使用全局变量

练习题目

Quiz1 寻找下标

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int n,num[100];
  6. cin >> n;
  7. for (int i = 0; i < n; i++) {
  8. cin >> num[i];
  9. }
  10. for (int i = 0; i < n; i++) {
  11. if(num[i] == i)
  12. {
  13. cout<<num[i]<<endl;
  14. break;
  15. }
  16. if(i == n-1)
  17. {
  18. cout<<"N"<<endl;
  19. break;
  20. }
  21. }
  22. return 0;
  23. }

Quiz2 四大湖

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. for (int d = 1; d <= 4; d++) {
  6. for (int h = 1; h <= 4; h++) {
  7. for (int t = 1; t <= 4; t++) {
  8. for (int p = 1; p <= 4; p++) {
  9. if((d!=h && d!=t && d!=p && h!=t && h!=p && t!=p) &&
  10. ((d==1)+(h==4)+(p==3) == 1)&&
  11. ((h==1)+(d==4)+(p==2)+(t==3) == 1)&&
  12. ((h==4)+(d==3) == 1)&&
  13. ((p==1)+(t==4)+(h==2)+(d==3) == 1))
  14. {
  15. cout << p << '\n' << d << '\n' << t << '\n' << h << endl;
  16. break;
  17. }
  18. }
  19. }
  20. }
  21. }
  22. return 0;
  23. }
  24. //这个题让我冥思苦想了好久orz
  25. //每人仅答对一个就等于所有表达式的和为1……

Quiz3 发票统计

  1. #include <iostream>
  2. #include <iomanip>
  3. using namespace std;
  4. int main()
  5. {
  6. double sumPerson[4] = {0.0}, sumType[4] = {0.0};
  7. char type[4] = {'\0','A','B','C'};
  8. int person,flag = 3;
  9. while (cin >> person)
  10. {
  11. int number;
  12. char tempC;
  13. double tempD;
  14. cin >> number;
  15. for (int i = 0; i < number; i++)
  16. {
  17. cin >> tempC >> tempD;
  18. sumPerson[person] += tempD;
  19. if(tempC == type[1])
  20. sumType[1] +=tempD;
  21. if(tempC == type[2])
  22. sumType[2] +=tempD;
  23. if(tempC == type[3])
  24. sumType[3] += tempD;
  25. }
  26. flag--;
  27. if(flag == 0)
  28. break;
  29. }
  30. for (int i = 1; i <= 3; i++)
  31. cout<<fixed<<setprecision(2)<<i<<" "<<sumPerson[i]<<endl;
  32. for (int i = 1; i <=3 ; i++)
  33. cout<<fixed<<setprecision(2)<<type[i]<<" "<<sumType[i]<<endl;
  34. return 0;
  35. }

Quiz4 Tomorrow never knows?

  1. #include <iostream>
  2. #include <iomanip>
  3. using namespace std;
  4. int get_year(int year, int month, int day)
  5. {
  6. if(month == 12 && day == 31)
  7. return year + 1;
  8. else return year;
  9. }
  10. int get_month(int year, int month, int day, bool leap_year)
  11. {
  12. if(day == 28 && month == 2 && !leap_year)
  13. return month + 1;
  14. if(day == 29 && month == 2 && leap_year)
  15. return month + 1;
  16. if(day == 30 && (month == 4 || month == 6 || month == 9 || month == 11))
  17. return month + 1;
  18. if(day == 31 && (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month ==10))
  19. return month + 1;
  20. if(day == 31 && month == 12)
  21. return 1;
  22. return month;
  23. }
  24. bool leap_year(int year)
  25. {
  26. return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
  27. }
  28. int main()
  29. {
  30. int y,m,d;
  31. char t1,t2;
  32. cin >> y >> t1 >> m >> t2 >> d;
  33. int ny = get_year(y,m,d);
  34. int nm = get_month(y,m,d,leap_year(y));
  35. int nd;
  36. if(get_month(y,m,d,leap_year(y)) == m)
  37. nd = d + 1;
  38. else nd = 1;
  39. cout<<ny<<'-'<<setw(2)<<setfill('0')<<nm<<'-'<<setw(2)<<setfill('0')<<nd;
  40. return 0;
  41. }

Quiz5 细菌实验分组

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int rate[101] = {0}, n;
  6. cin >> n;
  7. int maxDiff = 0;
  8. int index[101];
  9. int flag;
  10. for (int i = 1; i <= n ; i++) {
  11. int num,before,after;
  12. cin >> num >> before >> after;
  13. rate[num] = after / before;
  14. index[num] = num;
  15. }
  16. for (int i = 1; i <= n ; i++)
  17. for (int j = 1; j <= n - i ; j++)
  18. {
  19. if(rate[j] > rate[j+1])
  20. {
  21. int temp = rate[j];
  22. rate[j] = rate[j+1];
  23. rate[j+1] = temp;
  24. temp = index[j];
  25. index[j] = index[j+1];
  26. index[j+1] = temp;
  27. }
  28. }
  29. for (int i = 1; i <= n-1 ; i++) {
  30. if((rate[i+1]-rate[i]) > maxDiff)
  31. {
  32. maxDiff = rate[i+1] - rate[i];
  33. flag = i;
  34. }
  35. }
  36. cout<< n - flag <<endl;
  37. for (int i = flag+1; i <= n ; i++)
  38. {
  39. cout<<index[i]<<endl;
  40. }
  41. cout<< flag <<endl;
  42. for (int i = 1; i <= flag ; i++)
  43. {
  44. cout<<index[i];
  45. if(i == flag)
  46. break;
  47. else cout<<'\n';
  48. }
  49. return 0;
  50. }

Quiz6 流感传染

  1. #include <iostream>
  2. using namespace std;
  3. bool zuoOK(int i,int j,char matrix[100][100])
  4. {
  5. if(j != 0 && matrix[i][j-1] == '.')
  6. return true;
  7. else return false;
  8. }
  9. bool youOK(int i,int j,char matrix[100][100],int n)
  10. {
  11. if(j+1 < n && matrix[i][j+1] == '.')
  12. return true;
  13. else return false;
  14. }
  15. bool shangOK(int i,int j,char matrix[100][100])
  16. {
  17. if(i != 0 && matrix[i-1][j] == '.')
  18. return true;
  19. else return false;
  20. }
  21. bool xiaOK(int i,int j,char matrix[100][100],int n)
  22. {
  23. if(i+1 < n && matrix[i+1][j] == '.')
  24. return true;
  25. else return false;
  26. }
  27. bool zuoShangOK(int i,int j,char matrix[100][100])
  28. {
  29. if(i!=0 && j!= 0 && matrix[i-1][j-1] == '.')
  30. return true;
  31. else return false;
  32. }
  33. bool zuoXiaOK(int i,int j,char matrix[100][100],int n)
  34. {
  35. if(i+1<n && j!=0 && matrix[i+1][j-1] == '.')
  36. return true;
  37. else return false;
  38. }
  39. bool youShangOK(int i,int j,char matrix[100][100],int n)
  40. {
  41. if(j+1 < n && i != 0 && matrix[i-1][j+1] == '.')
  42. return true;
  43. else return false;
  44. }
  45. bool youXiaOK(int i,int j,char matrix[100][100],int n)
  46. {
  47. if(i+1 < n && j+1 < n && matrix[i+1][j+1] =='.')
  48. return true;
  49. else return false;
  50. }
  51. int main()
  52. {
  53. char room[100][100];
  54. int n;
  55. cin >> n;
  56. int numFlu = 0;
  57. for (int i = 0; i < n; i++)
  58. for (int j = 0; j < n; j++)
  59. {
  60. cin>>room[i][j];
  61. if(room[i][j] == '@')
  62. numFlu++;
  63. }
  64. int m;
  65. cin >> m;
  66. for (int p = 1; p < m; p++){
  67. for (int i = 0; i < n; i++)
  68. for (int j = 0; j < n; j++)
  69. {
  70. if(zuoOK(i,j,room) && room[i][j] == '@')
  71. {
  72. room[i][j-1] = 'n';
  73. numFlu++;
  74. }
  75. if(youOK(i,j,room,n)&& room[i][j] == '@')
  76. {
  77. room[i][j+1] = 'n';
  78. numFlu++;
  79. }
  80. if(shangOK(i,j,room)&& room[i][j] == '@')
  81. {
  82. room[i-1][j] = 'n';
  83. numFlu++;
  84. }
  85. if(xiaOK(i,j,room,n)&& room[i][j] == '@')
  86. {
  87. room[i+1][j] = 'n';
  88. numFlu++;
  89. }
  90. }
  91. for (int i = 0; i < n; i++)
  92. for (int j = 0; j < n; j++)
  93. if(room[i][j] == 'n')
  94. room[i][j] = '@';
  95. }
  96. cout<<numFlu<<endl;
  97. }
  98. //题目应该明说斜着不算临近啊!!!!害我白写了4个函数!!!QAQ

Coursera课程笔记----C程序设计进阶----Week 1&2的更多相关文章

  1. Coursera课程笔记----C程序设计进阶----Week 5

    指针(二) (Week 5) 字符串与指针 指向数组的指针 int a[10]; int *p; p = a; 指向字符串的指针 指向字符串的指针变量 char a[10]; char *p; p = ...

  2. Coursera课程笔记----C程序设计进阶----Week 4

    指针(一) (Week 4) 什么是"指针" 互联网上的资源--地址 当获得一个地址,就能得到该地址对应的资源,所以可以把"网址"称为指向资源的"指针 ...

  3. Coursera课程笔记----C程序设计进阶----Week 3

    函数的递归(Week 3) 什么是递归 引入 函数可以嵌套调用:无论嵌套多少层,原理都一样 函数不能嵌套定义:不能在一个函数里再定义另一个函数,因为所有函数一律平等 问题:一个函数能调用它自己吗? 举 ...

  4. Coursera课程笔记----C++程序设计----Week3

    类和对象(Week 3) 内联成员函数和重载成员函数 内联成员函数 inline + 成员函数 整个函数题出现在类定义内部 class B{ inline void func1(); //方式1 vo ...

  5. 操作系统学习笔记----进程/线程模型----Coursera课程笔记

    操作系统学习笔记----进程/线程模型----Coursera课程笔记 进程/线程模型 0. 概述 0.1 进程模型 多道程序设计 进程的概念.进程控制块 进程状态及转换.进程队列 进程控制----进 ...

  6. Coursera课程笔记----Write Professional Emails in English----Week 3

    Introduction and Announcement Emails (Week 3) Overview of Introduction & Announcement Emails Bas ...

  7. Coursera课程笔记----Write Professional Emails in English----Week 1

    Get to Know Basic Email Writing Structures(Week 1) Introduction to Course Email and Editing Basics S ...

  8. Coursera课程笔记----计算导论与C语言基础----Week 6

    理性认识C程序 导论(Week 6) 明确学习进度 讲课内容 感性➡️理性➡️函数➡️指针等 作业练习 初级阶段 ➡️正常作业练习 C语言的由来 程序设计语言的分类 低级语言之机器语言 0010101 ...

  9. Coursera课程笔记----计算导论与C语言基础----Week 4

    感性认识计算机程序(Week 4) 引入 编程序 = 给计算机设计好运行步骤 程序 = 人们用来告诉计算机应该做什么的东西 问题➡️该告诉计算机什么?用什么形式告诉? 如果要创造一门"程序设 ...

随机推荐

  1. 《JavaScript 模式》读书笔记(6)— 代码复用模式2

    上一篇讲了最简单的代码复用模式,也是最基础的,我们普遍知道的继承模式,但是这种继承模式却有不少缺点,我们下面再看看其它可以实现继承的模式. 四.类式继承模式#2——借用构造函数 本模式解决了从子构造函 ...

  2. 选择IT行业的自我心得,希望能帮助到各位!(四)

    俗话说,只有尝过人生的苦,吃过人生的亏,你才能吃一见长一智,人生教会了我们该如何去吃亏,该如何做人,该如何和人打交道,生活会让我们低下无数的头,就看你怎么去面对这些曲折该如何告诉自己不能就被这样打到, ...

  3. 第二章:shell变量

    查看所有全局和局部变量:delare和set 查看所有全局变量:env 定义环境变量: 用户变量在家目录下的~/.bash_profile和~/.bashrc中设置 全局变量在/etc/profile ...

  4. E2. Send Boxes to Alice (Hard Version)

    秒的有点难以理解:https://blog.csdn.net/weixin_42868863/article/details/103200132 #include<bits/stdc++.h&g ...

  5. 数据类型、运算符、Scanner的使用

              一.常见的基本数据类型      数值型  byte(最小,2字节)      short(4字节) int (默认 8字节)    long(16字节)      浮点型   f ...

  6. docx4j docx转html

    不好用,转完问题挺多,百度还找不到资料头疼.public static void docxToHtml(String fileUrl) throws Exception { String path = ...

  7. 终于明白if __name__ == '__main__':了

    其实很简单 if __name__ == '__main__': 就是一个判断 __name__是系统变量 __name__有一个特性,在当前文件运行是__main__,调用文件就是调用文件的路径了 ...

  8. python 基础篇 错误和异常处理

    语法错误 所谓语法错误,也就是你写的代码不符合编程规范,无法被识别与执行,比如下面这个例子: if name is not None print(name) If 语句漏掉了冒号,不符合 Python ...

  9. 权威的国际敏捷认证Certified Scrum Master (CSM)

    权威的国际敏捷认证Certified Scrum Master (CSM) A. 认证前 在学习Certified Scrum Master (CSM)之前,你需要了解: 什么是CSM CSM认证与其 ...

  10. pytorch seq2seq闲聊机器人

    cut_sentence.py """ 实现句子的分词 注意点: 1. 实现单个字分词 2. 实现按照词语分词 2.1 加载词典 3. 使用停用词 "" ...