Coursera课程笔记----C程序设计进阶----Week 1&2
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语言中,我们可以把所有程序都组织成函数
定义一个函数:
int absolute(int n)//n为形式参数,用于辅助进行函数定义,与实际参数相对
{
  if(n<0)
    return (-n);
	else
    return n;
}
float max(float a, float b)//2个形式参数的情况
{
  if(a > b)
    return a;
  else
    retuen b;
}
int get_int() //无参函数的例子
{
  int n = 0;
  cout<<"Please input an integer:"<<endl;
  cin >> n;
  return n;
}
void delay(int n) //无返回值函数的例子
{
  for(int i = 0; i < n* 100000;i++);
  return; //可不写
}
void show() //既无参数也无返回值的例子
{
  cout<<"***************************************";
  cout<<"********************show***************";
  cout<<"***************************************";
}
#include <iostream>
using namespace std;
int main() //程序执行的入口
{
  return 0;
}
//用void定义的main函数是老的C标准,因为无法获知调用结果所以该方式被放弃
函数调用的方式
- 作为独立语句
 - 作为表达式的一部分(存在一个计算式中)
 - 以实际参数形式出现在其他函数的调用中
 
函数是C程序的基本构成单位
- 一个C程序由一个或多个源文件组成
 - 一个源程序文件可以由一个或多个函数组成
 
函数的类型——函数的返回值的数据类型
可以在main函数的后面定义函数,但必须要在main函数前面先声明
函数原型&函数声明
函数原型
由函数的返回类型、函数名以及参数表构成的一个符号串,其中参数可不写名字
bool checkPrime(int)
函数的原型也叫函数的"Signature"
函数声明
- 函数在使用前都要声明,除非被调用函数的定义部分已经出现在主调函数之前
 - 在C语言中,函数声明=函数原型
 
函数的执行
- 在main函数中调用max函数的过程
- 在调用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,再计算出星期几,再减掉每年的天数(还要判断年是不是闰年),再减掉每月的天数(每月天数是不同的),从而逐步得到最终结果。
 
 
//主程序
#include<iostream>
using namespace std;
int days;
int get_dayofweek();
int get_year();
int get_month(int);
int main()
{
  int year,month,dayofweek;
  int leap_year;
  char week[7][10] = {"Saturday","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"};
    while((cin>>days) && days!= -1)
    {
      dayofweek = get_dayofweek();
      year = get_year();
      leap_year = (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
      month = get_month(leap_year);
      cout<<year<<"-"<<month<<"-"<<++days<<" "<<week[dayofweek];
    }
  return 0;
}
//计算星期几,2000年1月1日是周六
int get_dayofweek()
{
  return days % 7;
}
//计算年数
int get_year()
{
  int i = 2000, leap_year;
  while(1)
  {
    leap_year = (i % 4 == 0 && i % 100 != 0 || i % 400 == 0);
    if(leap_year == 1 && days >=366)
    {
      days = days - 366;
      i++;
      continue;
    }
    else if(leap_year == 0 && days >= 365)
    {
      days = days - 365;
      i++;
      continue;
    }
    else break;
  }
  return i;
}
//计算月份
int get_month(int leap_year)
{
  int pmonth[12] = {31,28,31,30,31,30,31,31,30,31,30,31}
  int rmonth[12] = {31,29,31,30,31,30,31,31,30,31,30,31}
  int j = 0;
  while(1)
  {
    if(leap_year == 1 && days >= rmonth[j])
    {
      days = days - rmonth[j];
      j++;
    }
    else if(leap_year == 0 && days >= pmonth[j])
    {
      days = days - pmonth[j];
      j++;
    }
    else break;
  }
  return ++j
}
//在该程序中,定义了全局变量days
//该变量在三个函数和主函数中都要使用,会带来一些问题:围绕着days的错误会影响所有函数
//
总结
- 全局变量
- 破坏了函数的相对独立性
 - 增加了函数之间的耦合性
 - 函数之间的交互不够清晰
 
 - 因此
- 在不是非常必要的情况下,不要使用全局变量
 
 
练习题目
Quiz1 寻找下标
#include <iostream>
using namespace std;
int main()
{
    int n,num[100];
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> num[i];
    }
    for (int i = 0; i < n; i++) {
        if(num[i] == i)
        {
            cout<<num[i]<<endl;
            break;
        }
        if(i == n-1)
        {
            cout<<"N"<<endl;
            break;
        }
    }
    return 0;
}
Quiz2 四大湖
#include <iostream>
using namespace std;
int main()
{
    for (int d = 1; d <= 4; d++) {
        for (int h = 1; h <= 4; h++) {
            for (int t = 1; t <= 4; t++) {
                for (int p = 1; p <= 4; p++) {
                    if((d!=h && d!=t && d!=p && h!=t && h!=p && t!=p) &&
                            ((d==1)+(h==4)+(p==3) == 1)&&
                            ((h==1)+(d==4)+(p==2)+(t==3) == 1)&&
                            ((h==4)+(d==3) == 1)&&
                            ((p==1)+(t==4)+(h==2)+(d==3) == 1))
                    {
                        cout << p << '\n' << d << '\n' << t << '\n' << h << endl;
                        break;
                    }
                }
            }
        }
    }
    return 0;
}
//这个题让我冥思苦想了好久orz
//每人仅答对一个就等于所有表达式的和为1……
Quiz3 发票统计
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    double sumPerson[4] = {0.0}, sumType[4] = {0.0};
    char type[4] = {'\0','A','B','C'};
    int person,flag = 3;
    while (cin >> person)
    {
        int number;
        char tempC;
        double tempD;
        cin >> number;
        for (int i = 0; i < number; i++)
        {
            cin >> tempC >> tempD;
            sumPerson[person] += tempD;
            if(tempC == type[1])
                sumType[1] +=tempD;
            if(tempC == type[2])
                sumType[2] +=tempD;
            if(tempC == type[3])
                sumType[3] += tempD;
        }
        flag--;
        if(flag == 0)
            break;
    }
    for (int i = 1; i <= 3; i++)
        cout<<fixed<<setprecision(2)<<i<<" "<<sumPerson[i]<<endl;
    for (int i = 1; i <=3 ; i++)
        cout<<fixed<<setprecision(2)<<type[i]<<" "<<sumType[i]<<endl;
    return 0;
}
Quiz4 Tomorrow never knows?
#include <iostream>
#include <iomanip>
using namespace std;
int get_year(int year, int month, int day)
{
    if(month == 12 && day == 31)
        return year + 1;
    else return year;
}
int get_month(int year, int month, int day, bool leap_year)
{
    if(day == 28 && month == 2 && !leap_year)
        return month + 1;
    if(day == 29 && month == 2 && leap_year)
        return month + 1;
    if(day == 30 && (month == 4 || month == 6 || month == 9 || month == 11))
        return month + 1;
    if(day == 31 && (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month ==10))
        return month + 1;
    if(day == 31 && month == 12)
        return 1;
    return month;
}
bool leap_year(int year)
{
    return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
}
int main()
{
    int y,m,d;
    char t1,t2;
    cin >> y >> t1 >> m >> t2 >> d;
    int ny = get_year(y,m,d);
    int nm = get_month(y,m,d,leap_year(y));
    int nd;
    if(get_month(y,m,d,leap_year(y)) == m)
        nd = d + 1;
    else nd = 1;
    cout<<ny<<'-'<<setw(2)<<setfill('0')<<nm<<'-'<<setw(2)<<setfill('0')<<nd;
    return 0;
}
Quiz5 细菌实验分组
#include <iostream>
using namespace std;
int main()
{
    int rate[101] = {0}, n;
    cin >> n;
    int maxDiff = 0;
    int index[101];
    int flag;
    for (int i = 1; i <= n ; i++) {
        int num,before,after;
        cin >> num >> before >> after;
        rate[num] = after / before;
        index[num] = num;
    }
    for (int i = 1; i <= n ; i++)
        for (int j = 1; j <= n - i ; j++)
        {
            if(rate[j] > rate[j+1])
            {
                int temp = rate[j];
                rate[j] = rate[j+1];
                rate[j+1] = temp;
                temp = index[j];
                index[j] = index[j+1];
                index[j+1] = temp;
            }
        }
    for (int i = 1; i <= n-1 ; i++) {
        if((rate[i+1]-rate[i]) > maxDiff)
        {
            maxDiff = rate[i+1] - rate[i];
            flag = i;
        }
    }
    cout<< n - flag <<endl;
    for (int i = flag+1; i <= n ; i++)
    {
        cout<<index[i]<<endl;
    }
    cout<< flag <<endl;
    for (int i = 1; i <= flag ; i++)
    {
        cout<<index[i];
        if(i == flag)
            break;
        else cout<<'\n';
    }
    return 0;
    }
Quiz6 流感传染
#include <iostream>
using namespace std;
bool zuoOK(int i,int j,char matrix[100][100])
{
    if(j != 0 && matrix[i][j-1] == '.')
        return true;
    else return false;
}
bool youOK(int i,int j,char matrix[100][100],int n)
{
    if(j+1 < n && matrix[i][j+1] == '.')
        return true;
    else return false;
}
bool shangOK(int i,int j,char matrix[100][100])
{
    if(i != 0 && matrix[i-1][j] == '.')
        return true;
    else return false;
}
bool xiaOK(int i,int j,char matrix[100][100],int n)
{
    if(i+1 < n && matrix[i+1][j] == '.')
        return true;
    else return false;
}
bool zuoShangOK(int i,int j,char matrix[100][100])
{
    if(i!=0 && j!= 0 && matrix[i-1][j-1] == '.')
        return true;
    else return false;
}
bool zuoXiaOK(int i,int j,char matrix[100][100],int n)
{
    if(i+1<n && j!=0 && matrix[i+1][j-1] == '.')
        return true;
    else return false;
}
bool youShangOK(int i,int j,char matrix[100][100],int n)
{
    if(j+1 < n && i != 0 && matrix[i-1][j+1] == '.')
        return true;
    else return false;
}
bool youXiaOK(int i,int j,char matrix[100][100],int n)
{
    if(i+1 < n && j+1 < n && matrix[i+1][j+1] =='.')
        return true;
    else return false;
}
int main()
{
    char room[100][100];
    int n;
    cin >> n;
    int numFlu = 0;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
        {
            cin>>room[i][j];
            if(room[i][j] == '@')
                numFlu++;
        }
    int m;
    cin >> m;
    for (int p = 1; p < m; p++){
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
            {
                if(zuoOK(i,j,room) && room[i][j] == '@')
                {
                    room[i][j-1] = 'n';
                    numFlu++;
                }
                if(youOK(i,j,room,n)&& room[i][j] == '@')
                {
                    room[i][j+1] = 'n';
                    numFlu++;
                }
                if(shangOK(i,j,room)&& room[i][j] == '@')
                {
                    room[i-1][j] = 'n';
                    numFlu++;
                }
                if(xiaOK(i,j,room,n)&& room[i][j] == '@')
                {
                    room[i+1][j] = 'n';
                    numFlu++;
                }
            }
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                if(room[i][j] == 'n')
                    room[i][j] = '@';
    }
    cout<<numFlu<<endl;
}
//题目应该明说斜着不算临近啊!!!!害我白写了4个函数!!!QAQ
												
											Coursera课程笔记----C程序设计进阶----Week 1&2的更多相关文章
- Coursera课程笔记----C程序设计进阶----Week 5
		
指针(二) (Week 5) 字符串与指针 指向数组的指针 int a[10]; int *p; p = a; 指向字符串的指针 指向字符串的指针变量 char a[10]; char *p; p = ...
 - Coursera课程笔记----C程序设计进阶----Week 4
		
指针(一) (Week 4) 什么是"指针" 互联网上的资源--地址 当获得一个地址,就能得到该地址对应的资源,所以可以把"网址"称为指向资源的"指针 ...
 - Coursera课程笔记----C程序设计进阶----Week 3
		
函数的递归(Week 3) 什么是递归 引入 函数可以嵌套调用:无论嵌套多少层,原理都一样 函数不能嵌套定义:不能在一个函数里再定义另一个函数,因为所有函数一律平等 问题:一个函数能调用它自己吗? 举 ...
 - Coursera课程笔记----C++程序设计----Week3
		
类和对象(Week 3) 内联成员函数和重载成员函数 内联成员函数 inline + 成员函数 整个函数题出现在类定义内部 class B{ inline void func1(); //方式1 vo ...
 - 操作系统学习笔记----进程/线程模型----Coursera课程笔记
		
操作系统学习笔记----进程/线程模型----Coursera课程笔记 进程/线程模型 0. 概述 0.1 进程模型 多道程序设计 进程的概念.进程控制块 进程状态及转换.进程队列 进程控制----进 ...
 - Coursera课程笔记----Write Professional Emails in English----Week 3
		
Introduction and Announcement Emails (Week 3) Overview of Introduction & Announcement Emails Bas ...
 - 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 ...
 - Coursera课程笔记----计算导论与C语言基础----Week 6
		
理性认识C程序 导论(Week 6) 明确学习进度 讲课内容 感性➡️理性➡️函数➡️指针等 作业练习 初级阶段 ➡️正常作业练习 C语言的由来 程序设计语言的分类 低级语言之机器语言 0010101 ...
 - Coursera课程笔记----计算导论与C语言基础----Week 4
		
感性认识计算机程序(Week 4) 引入 编程序 = 给计算机设计好运行步骤 程序 = 人们用来告诉计算机应该做什么的东西 问题➡️该告诉计算机什么?用什么形式告诉? 如果要创造一门"程序设 ...
 
随机推荐
- ValidForm.js的使用注意点
			
dataType的值不能为"", 否则会导致错误发生:Uncaught TypeError: Cannot read property '0' of null,http请求可以发送 ...
 - 记录d3.js 力导向图的平移缩放,类似地图导航点击某一项移动到当前位置
			
项目中有用到d3.js用于图结构的查询, 需求如下: 右上角有个模糊搜索功能,查询出来的结果用列表展示 点击列表的某一列,要求画布移动到当前选中的节点的位置,基于画布正中间 搜索出来的结果列表展示用的 ...
 - stand up meeting for beta release plan 12/16/2015
			
今天我们开会讨论一下beta版需要的feature,其中待定的feature是可选做的,如果有时间.其他都是必须实现的. 因为做插件的计划失败了,所以我们现在是pdf阅读器和取词查词加入生词本这两部分 ...
 - B - Cow Marathon  DFS+vector存图
			
After hearing about the epidemic of obesity in the USA, Farmer John wants his cows to get more exerc ...
 - Java核心技术--接口与内部类
			
接口implement 继承接口,即履行"义务". 接口中所有的方法自动属于public,在接口声明中,不必提供关键字public 接口中决不能含有实例域,也不能在接口中实现方法 ...
 - Spring Boot 中使用自定义注解,AOP 切面打印出入参日志及Dubbo链路追踪透传traceId
			
一.使用背景 开发排查系统问题用得最多的手段就是查看系统日志,在分布式环境中一般使用 ELK 来统一收集日志,但是在并发大时使用日志定位问题还是比较麻烦,由于大量的其他用户/其他线程的日志也一起输出穿 ...
 - [Yii2] 快速套模板,加载JS,CSS(HTML标签<base>)
			
刚开始学,弄了好久,不知道怎么加载JS.CSS,以及怎么不加载YII2自带的模板!其实真的好简单! 补: 其实是我垃圾,YII2默认访问路径是WEB,所以把style文件放到web下就能加载! 首先把 ...
 - [Abp vNext 入坑分享] - 4.JWT授权的接入
			
一.感想 在写这一系列文章之前,本来以为写这个之前已经搭建好的框架描述会比较简单,但是慢慢写下来才发现.写这个真的不简单额,本来以为图文一起,一个晚上应该能输出一篇吧...结果:现实真的骨感,一个星期 ...
 - 8、Flink Table API & Flink Sql API
			
一.概述 上图是flink的分层模型,Table API 和 SQL 处于最顶端,是 Flink 提供的高级 API 操作.Flink SQL 是 Flink 实时计算为简化计算模型,降低用户使用实时 ...
 - thinkphp5.0 url跳转
			
<a href="{:url('member/index/index',['id'=>5])}">跳转</a> define()自定义常量在thiin ...