本笔记记录自 Coursera课程 《计算机程式设计》 台湾大学 刘邦锋老师

Week4 Functions

4-1 System Function

函数主要分为两大类系统定义函数使用者定义函数,例如printf和main。

例子:(sys-function.c)呼叫系统定义函数

#include <stdio.h> /* for printf and scanf */
#include <stdlib.h> /* for abs */
#include <math> /* for sin */
main()
{
int i, j;
double x, y;
scanf("%d", &i);
j = abs(i);
printf("%d\n", j);
scanf("%lf", &x);
y = sin(x);
printf("%f\n", y);
}

需要使用的系统定义函数,可以在网络上查找到它存在于哪个库中,方便调用。比如说课程中提到的这个网址

  • 函数名称,参数,及返回值合称为函数的原型
  • 函数的原型就好像是函数的使用说明书,详细记载函数应该如何使用。
  • 系统函数的原型都是定义在对应的标头档(类似python的库)内。

3 4-2 System Function Return Value

例子:(scanf-count.c)借由scanf的返回值掌握资料个数

#include <stdio.h>

int main()
{
int sum = 0;
int count = 0;
int i; while (scanf("%d", &i) != EOF){
sum += i;
count++;
}
printf("%d\n", sum / count);
return 0;
}

4-3 User Function Definition

如果定义一个接受一个整数参数i,并返回一个整数的函数myfuntion:

  • 先写返回值的类别int,再写函数的名称myfunction,最后用小括号( )将参数的类别int,及名称i括起来。
  • 此时不只描述函数的原型,也要定义函数如何操作,所以不能像函数原型直接用分号结束,而是要用一对{ }将操作的部分包起来,就像写main主程式一样。
  • 因为我们要返回一个整数,所以我们申明一个整数变量value,并根据参数i计算value,最后使用return命令将value返回。
int myfunction(int i)
{
int value;
...
compute value according to i;
...
return value;
}

例子:返回一个整数的main

#include <stdio.h>
int main(void)
{
return 0;
}
  • main主程式是一个没有参数,担忧一个整数返回值的函数。而且通常我们将返回值设为0.
  • 由于main不需要任何参数,所以main后面的( )中以void来表示。
  • void表示的是没有

例子:(leap-year-function.c)定义一个函数决定闰年

#include <stdio.h>
int leap_year(int y)
{
int is_leap;
is_leap = (y % 400 == 0) || ((y % 4 == 0) && !(y % 100 == 0));
return is_leap;
}
int main(void)
{
int year;
int k;
scanf("%d", &year);
k = leap_year(year);
printf("%d\n", k);
return 0;
}

可以重复使用写好的函数。重复的代码不仅会让程序冗长难以理解,而且很容易在重复撰写时出错。如果使用已经过验证的函数,则可以避免这些麻烦。

4-4 User Function With Return Value

定义一个接受一个整数参数i,但不返回任何值的函数foo:

  • 使用void表示foo并没有任何返回值。void不可省略,否则编译器会假设返回值类别为int。
void foo(int i)
{
...
process according to i;
...
return;
}

例子:(print-digits.c)印出一个数的各位数

#include <stdio.h>
void print_digits(int i)
{
int index = 0;
int digits[20];
if (i < 0)
return;
while (i != 0){
digits[index] = (i % 10);
i /= 10;
index++;
}
for (i = index - 1; i >= 0; i --)
printf("%d\n", digits[i]);
return;
}
int main(void)
{
int i;
scanf("%d", &i);
print_digits(i);
return 0;
}

4-5 Use Function to Simplify Program

其实就是把重复的代码整合在函数里,可以简化代码。

4-6 Printf Scanf for Multiple Variables and Extra Message

函数原型:printf-scanf

int printf(char *format, ...);
int scanf(char *format, ...);
  • 第二个参数非常奇特,是...,意思是参数个数是不固定的。
  • 之前printf及scanf都一次处理一个变量,但是"..."不固定参数个数能让我们同时对多个变量作输出入。

例子:对多个变量作输出输入

printf("%d %p %f %f\n", int, addr, float, double);
scanf("%d%f%lf", &int, &float, &double)

例子:(multi-io-message.c)输出夹杂其他字元

#include <stdio.h>
int main(void)
{
int i;
float f;
double df;
scanf("%d%f%lf", &i, &f ,&df);
printf("int %d adr %p flt %f dbl %f\n",i &i, f, df);
return 0;
}

则如输入

-1 3.2 4.6

输出为

int -1 adr 0x7fff98a1f330 flt 3.200000 dbl 4.600000

4-7 Scanf with Nonspace Char in Format String

就是说scanf也可以夹杂其他字元,但是输入形式一定要与其相对应,不然会读不全。

4-8 Function Parameter Passing

  • 形式参数(formal parameter)就是写在被呼叫方函数的申明部分,所以一定是一个变量的类别。例如j就是test的形式参数。

    void test(int j)
  • 实际参数(actual parameter)是呼叫方实际用以呼叫被呼叫函数的参数。实际参数可以是一个算式,并不一定是一个变量。

    test(i);
    test(3 + 7);

4-9 Funtion Array Parameter Passing

例子:使用函数处理一个数组中的元素

void process_array(int array[], int n)
{
int i;
for (i = 0; i < n; i++)
process element array[i];
return;
}
int main(void)
{
int a[10];
process_array(a,10);
return 0;
}

这里注意形式参数array申明要写成array[]。

4-10 Function Array Parameter Passing with Modification

例子:(partial-inc.c)增加部分阵列元素的值

#include <stdio.h>
void print_array(int array[], int n)
{
int i;
for (i = 0; i < n; i++)
printf("a[%d] = %d\n", i, array[i]);
return;
}
void inc_array(int array[], int n)
{
int i;
printf("inc_array: array = %p\n", array);
for (i = 0; i < n; i++)
array[i]++;
return;
}
int main(void)
{
int i;
int a[5];
for (i = 0; i < 5; i++)
scanf("%d", &(a[i]));
printf("before inc_array\n");
print_array(a, 5);
inc_array(a, 5);
printf("after first inc_array\n");
print_array(a, 5);
inc_array(&(a[1]), 2);
printf("after second inc_array\n");
print_array(a, 5);
inc_array(&(a[2]), 2);
printf("after third inc_array\n");
print_array(a, 5);
return 0;
}
  • 第一次实际参数是(a, 5),所以inc_array中的形式参数array会拿到数组a的起始位址,并将整个数组加1。
  • 第二次实际参数是(&(a[1]), 2),所以inc_array中的形式参数array会拿到元素a[1]的位址,并将a[1]及a[2]加1。
  • 第三次实际参数是(&(a[2]), 2),所以inc_array中的形式参数array会拿到元素a[2]的位址,并将a[2]及a[3]加1。

4-11 Function Multi-dimension Array Parameter Passing

例子:(multi-dim-array-parameter.c)传递多维数组参数

#include <stdio.h>
void print_matrix(int a[4][3], int i, int j)
{
printf("a[%d][%d] = %d\n", i, j, a[i][j]);
return;
}
int main(void)
{
int i, j;
int array[3][4];
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
scanf("%d", &(array[i][j]));
printf("array[2][1] = %d\n", array[2][1]);
print_matrix(array, 2, 1);
printf("array[0][2] = %d\n", array[0][2]);
print_matrix(array, 0, 2);
return 0;
}

注意,我们在main函数中申明的array是3,4,而print_matrix函数中申明的形式参数array是4,3。

输入

0 1 2 3
4 5 6 7
8 9 10 11

输出

array[2][1] = 9
a[2][1] = 7
array[0][2] = 2
a[0][2] = 2

why??因为

测验代码

因为不会算长方体可以分割多少个大小相等的正方体,凭感觉乱写了一个4/5的测验代码,与老师的相差那么一丢丢吧。

我的代码

#include <stdio.h>
int value(int type, int width, int height, int length)
{
if ((type != 79) && (type != 47) && (type != 29) && (type != 82) && (type != 26) && (type != 22))
return -1;
if ((width <= 0) || (height <= 0) || (length <= 0))
return -2;
int value;
// 找到最小的边长
int t;
if (width > height)
t = height;
else
t = width;
if (t > length)
t = length;
// 求正方体的边长和个数
int v1, n, a, v;
v1 = width * height * length;
for (a = t; a > 0; a--){
v = a * a * a;
if ( v1 % v == 0){
n = v1 / v;
break;
}
}
switch(type){
case 79:
value = v * v * n * 30;
break;
case 47:
value = v * v * n * 10;
break;
case 29:
value = v * v * n * 4;
break;
case 82:
value = v * v * n * 5;
break;
case 26:
value = v * v * n * 3;
break;
case 22:
value = v * v * n * 9;
break;
default:
value = 0;
}
return value;
}
int main ()
{
int type, width, height, length;
scanf ( "%d%d%d%d", &type, &width, &height, &length );
printf ( "%d", value ( type, width, height, length ) );
return 0;
}

老师的代码

#include <stdio.h>

int gcd ( int a, int b )
{
if ( a < b ) return gcd ( b, a ); if ( b == 0 )
return a;
else
return gcd ( b, a % b );
} int value ( int type, int width, int height, int length )
{
int u_val; switch ( type ) {
case 79:
u_val = 30;
break;
case 47:
u_val = 10;
break;
case 29:
u_val = 4;
break;
case 82:
u_val = 5;
break;
case 26:
u_val = 3;
break;
case 22:
u_val = 9;
break;
default :
return -1;
} if ( width <= 0 || height <= 0 || length <= 0 )
return -2; int s = gcd ( gcd ( width, height ), gcd ( height, length ) );
int v = s * s * s;
int count = ( width / s ) * ( height / s ) * ( length / s ); return v * v * count * u_val;
}

《计算机程式设计》Week4 课堂笔记的更多相关文章

  1. 【C语言】Coursera课程《计算机程式设计》台湾大学刘邦锋——Week6 String课堂笔记

    Coursera课程 <计算机程式设计>台湾大学 刘邦锋 Week6 String 6-1 Character and ASCII 字符变量的声明 char c; C语言使用一个位元组来储 ...

  2. 《计算机程式设计》Week5 课堂笔记

    本笔记记录自 Coursera课程 <计算机程式设计> 台湾大学 刘邦锋老师 Week5 Pointer 5-1 Pointer Definition and Declaration 指针 ...

  3. 《计算机程式设计》Week3 课堂笔记

    本笔记记录自 Coursera课程 <计算机程式设计> 台湾大学 刘邦锋老师 Week3 Array 3-1 Array Usage 例子:使用数组一次申明10个整数变量 int a[10 ...

  4. 《计算机程式设计》Week2 课堂笔记

    本笔记记录自 Coursera课程 <计算机程式设计> 台湾大学 刘邦锋老师 Week2 Control Structure 2-1 If-then-else if then 判断 if ...

  5. 九章算法系列(#3 Binary Tree & Divide Conquer)-课堂笔记

    前言 第一天的算法都还没有缓过来,直接就进入了第二天的算法学习.前一天一直在整理Binary Search的笔记,也没有提前预习一下,好在Binary Tree算是自己最熟的地方了吧(LeetCode ...

  6. 九章算法系列(#5 Linked List)-课堂笔记

    前言 又是很长时间才回来发一篇博客,前一个月确实因为杂七杂八的事情影响了很多,现在还是到了大火燃眉毛的时候了,也应该开始继续整理一下算法的思路了.Linked List大家应该是特别熟悉不过的了,因为 ...

  7. 九章算法系列(#4 Dynamic Programming)-课堂笔记

    前言 时隔这么久才发了这篇早在三周前就应该发出来的课堂笔记,由于懒癌犯了,加上各种原因,实在是应该反思.好多课堂上老师说的重要的东西可能细节上有一些急记不住了,但是幸好做了一些笔记,还能够让自己回想起 ...

  8. 九章算法系列(#2 Binary Search)-课堂笔记

    前言 先说一些题外的东西吧.受到春跃大神的影响和启发,推荐了这个算法公开课给我,晚上睡觉前点开一看发现课还有两天要开始,本着要好好系统地学习一下算法,于是就爬起来拉上两个小伙伴组团报名了.今天听了第一 ...

  9. ocp11g培训内部教材_052课堂笔记(042)_体系架构

    OCP 052 课堂笔记 目录 第一部分: Oracle体系架构... 4 第一章:实例与数据库... 4 1.Oracle 网络架构及应用环境... 4 2.Oracle 体系结构... 4 3. ...

随机推荐

  1. 2019 上海市大学生网络安全大赛 RE部分WP

    这次比赛就做了这一道逆向题,看到队友的WP,下面的对v10的加密方式为RC4,从我提取的v4数组就能够察觉出这是CR4了,自己傻乎乎的用OD调试,跟踪数据半天才做出来,还是见得的少了... ...下面 ...

  2. Python webdriver调用Chrome报错

    报错信息如下: selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to b ...

  3. 看完阮一峰的React教程后, 我写了一个TodoList

    看完阮一峰的React教程后,就自己做了这个TodoList,自己慢慢琢磨效率差了点但是作为入门小练习还是不错的. 以下是效果图:我的源码:todolistUI:bootstrap 4 一.组件化 我 ...

  4. ThinkPHP中的"路由"是什么意思?

    路由(route)是指根据url, 分配到对应的处理程序的映射. 简单来说,就是一个路径的解析,根据客户端提交的路径,将请求解析到相应的模块/控制器/方法上. 转载自:https://blog.csd ...

  5. Centos6.6安装apache2.4

    安装apr请参考:   http://www.cnblogs.com/yuzhaokai0523/p/4382974.html 1安装httpd-2.4.10.tar.gz wget http://w ...

  6. 北京太速科技股份有限公司产品手册V201903020

    如果您无法正常查看,请点击在线浏览                                           如果您无法正常查看,请点击在线浏览 了解更多产品信息,请扫描二维码,期待您的关注 ...

  7. Python实现IP地址归属地查询

    一.使用淘宝IP地址库查询 使用淘宝的Rest API,可以快速查询IP地址的归属地: 图00-淘宝IP地址库RestAPI使用说明 图01-使用淘宝免费IP地址库-查询IP归属地 存在问题:淘宝的免 ...

  8. git log混乱之混乱操作

    好几个分支 然后就混乱了 git log信息一坨屎 git 删除某次指定的提交 git reset只是在本地仓库中回退版本,而远程仓库的版本不会变化. 以删除master分支为例 #新建一个备份的分支 ...

  9. 2018-11-11-weekly

    Algorithm 601. 体育馆的人流量 What X 市建了一个新的体育馆,每日人流量信息被记录在这三列信息中:序号 (id).日期 (date). 人流量 (people).请编写一个查询语句 ...

  10. java 工具包

    https://www.cnblogs.com/aligege/p/8521934.html https://gitee.com/loolly/hutool https://blog.csdn.net ...