本笔记记录自 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. JS事件流、事件监听、事件对象、事件委托

    JS事件流: 01.DOM级别和DOM事件 02.JS事件流:页面中接收事件的顺序 事件冒泡阶段-->处于目标阶段-->事件捕获阶段 (事件捕获总发生在事件冒泡前面) 03.捕获:从外向里 ...

  2. reactV16理解

    在 V16 版本中引入了 Fiber 机制.这个机制一定程度上的影响了部分生命周期的调用,并且也引入了新的 2 个 API 来解决问题. 在之前的版本中,如果你拥有一个很复杂的复合组件,然后改动了最上 ...

  3. 2014-04-27 南江滨大道 6KM 晴

    33分41秒,6.03公里,慢速跑,中间有停了几次拍照 天气不错,多云 人,不多 不知道这货叫啥 2个大人3个小孩,跳绳,小时候的回忆,啊哈 老中少三代,捡风筝也是一种幸福 一家三口,江滨散步,惬意至 ...

  4. nroff - 用 groff 模拟 nroff 命令

    总览 (SYNOPSIS) nroff [ -h ] [ -i ] [ -mname ] [ -nnum ] [ -olist ] [ -rcn ] [ -Tname ] [ file... ] 描述 ...

  5. Keepalived高可用服务器案例

    部署Keepalived高可用软件,实现如下: - 使用Keepalived实现web服务器的高可用 - Web服务器IP地址分别为192.168.4.100和192.168.4.200 - Web服 ...

  6. Beta冲刺-(1/3)

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/ 这个作业要求在哪里 https://edu.cnbl ...

  7. [USACO12DEC]第一!First!(字典树,拓扑排序)

    [USACO12DEC]第一!First! 题目描述 Bessie has been playing with strings again. She found that by changing th ...

  8. pycharm快捷键的使用、内存管理、变量、数据类型、注释相关笔记

    目录 pycharm快捷键的使用 变量 python内存管理 小整数池 引用计数 垃圾回收机制 循环引用 变量的三种打印形式 数字类型 字符串 注释 pycharm快捷键的使用 ctrl+c复制,默认 ...

  9. [转帖]ssh 远程执行命令

    ssh 远程执行命令 https://www.cnblogs.com/youngerger/p/9104144.html SSH 是 Linux 下进行远程连接的基本工具,但是如果仅仅用它来登录那可是 ...

  10. 【python】对于程序员来说,2018刑侦科推理试卷是问题么?

    最近网上很火的2018刑侦科推理试卷,题目确实很考验人逻辑思维能力. 可是对于程序员来说,这根本不是问题.写个程序用穷举法计算一遍即可,太简单. import itertools class Solu ...