Function.

Slides:



Advertisements
Similar presentations
CSIM, PU C Language Introduction to the C Programming Language 重覆敘述 (for,while,break,continue) 適合重複性的計算或判斷.
Advertisements

“八皇后”问题 崔萌萌 吕金华.
行程(process).
Loops.
第一章 C语言概述 计算机公共教学部.
第九章 字串 (String).
TQC+ 物件導向程式認證-JAVA.
第8章 字元與字串處理 8-1 C語言的字元檢查函數 8-2 C語言的字串 8-3 字串的輸入與輸出 8-4 指標與字串
第一章 程序设计入门.
Introduction to the C Programming Language
高级语言程序设计 主讲人:陈玉华.
由C程序结构所知,一个完整的C语言程序是由一个且只能有一个main()函数(又称主函数)和若干个其他函数组合而成的。而前面各章仅学习main()函数的编程,本章将介绍其他函数的编程,包括其他函数的定义、调用、参数传递及变量的作用域等。
主讲教师:吴琼 微信群:C语言2016 QQ群: 密码scu2016 昵称:“真名+学号”
物件導向程式設計 (Object-Oriented rogramming)
C的發展史 C程式初體驗 C程式設計基本注意事項 上機實習課程
函數(一) 自訂函數、遞迴函數 綠園.
Chap 10 函数与程序结构 10.1 函数的组织 10.2 递归函数 10.3 宏定义 10.4 编译预处理.
If … else 選擇結構 P27.
C 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
Chap 2 用C语言编写程序 2.1 在屏幕上显示 Hello World! 2.2 求华氏温度 100°F 对应的摄氏温度
Introduction to the C Programming Language
C++ 程式設計— 語言簡介 台大資訊工程學系 資訊系統訓練班.
STRUCTURE 授課:ANT 日期:2010/5/12.
第七章 函数 目录 有参的加法函数的开发 函数定义的一般形式 函数参数和函数的值 函数的调用
第 6 章 函式.
程式撰寫流程.
Chap 8 指针 8.1 寻找保险箱密码 8.2 角色互换 8.3 冒泡排序 8.4 电码加密 8.5 任意个整数求和*
程序设计专题一 结构化程序设计与递归函数 主讲教师: 刘新国.
第八章 函数.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第7章 编译预处理 本章要求: 本章重点: 本章难点: 掌握用#define定义无参数宏和带有参数宏定义和调用方法;
Introduction to the C Programming Language
Chap 3 分支结构 3.1 简单的猜数游戏 3.2 四则运算 3.3 查询自动售货机中商品的价格.
第3章 堆栈和队列 堆栈 堆栈应用 队列 队列应用 优先级队列 主要知识点.
C语言 程序设计基础与试验 刘新国、2012年秋.
期中考试成绩分布 《程序设计》-2017年秋.
本章中將會更詳細地考慮有關重複的概念,並且會 介紹for和do…while等兩種用來控制重複的敘述 式。 也將會介紹switch多重選擇敘述式。 我們會討論直接和迅速離開某種控制敘述式的 break敘述式,以及用來跳過重複敘述式本體剩餘 部份的continue敘述式。 本章會討論用來組合控制條件的邏輯運算子,最後.
計數式重複敘述 for 迴圈 P
第十章 指针.
东北林业大学 陈宇 ACM程序设计 东北林业大学 陈宇
第5讲 结构化程序设计(Part II) 周水庚 2018年10月11日.
第七章 函数及变量存贮类型 7.1 函数基础与C程序结构 7.2 函数的定义和声明 7.3 函数的调用 7.4 函数的嵌套与递归
Struct結構 迴圈
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
C语言概述 第一章.
Chapter 2 & Chapter 3.
C语言大学实用教程 第5章 函数与程序结构 西南财经大学经济信息工程学院 刘家芬
for 迴圈 while迴圈 do-while迴圈 break 與 continue goto 與 標籤 程式觀摩
C语言复习2----函数.
Introduction to the C Programming Language
Oop8 function函式.
指標
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
Chap 5 函数 5.1 计算圆柱体积 5.2 数字金字塔 5.3 复数运算.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
輸出與輸入(I/O).
第十四章 若干深入问题和C独有的特性 作业: 函数指针 函数作参数 函数副作用 运算 语句 位段 存储类别 编译预处理
C程序设计.
第5章 函 数.
資料結構與C++程式設計進階 遞迴(Recursion) 講師:林業峻 CSIE, NTU 6/ 17, 2010.
Introduction to the C Programming Language
第四章 C 语言中的输入和输出.
C程序设计.
挑戰C++程式語言 ──第9章 函數.
Introduction to the C Programming Language
C/C++基礎程式設計班 字元與字串 講師:林業峻 CSIE, NTU 3/14, 2015.
C/C++基礎程式設計班 C語言入門、變數、基本處理與輸入輸出 講師:林業峻 CSIE, NTU 3/7, 2015.
Chap 10 函数与程序结构 10.1 圆形体积计算器 10.2 汉诺塔问题 10.3 长度单位转换 10.4 大程序构成.
Q1(a) 小偉打算編寫一個程序。該程序把兩個44的表內的數字相加。表3內的數字是由表1和表2應格子內的數字相加而成。例如:
Introduction to the C Programming Language
Presentation transcript:

Function

輸出: #include <stdio.h> #include <string.h> #define NAME "NTHU CS" #define ADDRESS "101, Sec. 2, Kuang Fu Rd." #define PLACE "Hsinchu, 300 Taiwan" #define WIDTH 40 #define SPACE ' ' void show_n_char(char ch, int num); int main(void) {    int spaces;    show_n_char('*', WIDTH);    putchar('\n');    show_n_char(SPACE, 17);    printf("%s\n", NAME);    spaces = (WIDTH - strlen(ADDRESS)) /2;    show_n_char(SPACE, spaces);    printf("%s\n", ADDRESS);    show_n_char(SPACE, (WIDTH - strlen(PLACE)) / 2);    printf("%s\n", PLACE);    return 0; } void show_n_char(char ch, int num)    int count;    for (count = 1; count <= num; count++)       putchar(ch); 輸出: **************************************** NTHU CS 101, Sec. 2, Kuang Fu Rd. Hsinchu, 300 Taiwan 範例3-1

它做的事情很簡單,只要一個 for 迴圈就可以辦到 void show_n_char(char ch, int num); int main(void) {...} void show_n_char(char ch, int num) {    int count;    for (count = 1; count <= num; count++)       putchar(ch); } 我們用自訂的 show_n_char()來輸出一長條以相同字元組成 的字串,我們希望 show_n_char()要傳入兩個參數,分別用來指 定輸出的字元以及長度 它做的事情很簡單,只要一個 for 迴圈就可以辦到 宣告 (prototype) 的地方要寫 void show_n_char(char ch, int num); 表示第一個參數的型別是 char,第二個參數的型別是 int。傳 回值的型別則還是寫 void,表示不需要回傳任何值

其實在宣告的時候,變數名稱並不重要,重要的是型別要寫對 void show_n_char(char ch, int num); int main(void) {...} void show_n_char(char ch, int num) {    int count;    for (count = 1; count <= num; count++)       putchar(ch); } 其實在宣告的時候,變數名稱並不重要,重要的是型別要寫對 所以 function 宣告也可以寫成 void show_n_char(char , int ); 因為宣告的時候,還不需要真正產生變數。要等到定義的時候, 才需要產生變數,那時候就一定要寫變數名稱。

   show_n_char('*', WIDTH);    show_n_char(SPACE, 17);    spaces = (WIDTH - strlen(ADDRESS)) /2;    show_n_char(SPACE, spaces);    show_n_char(SPACE, (WIDTH - strlen(PLACE)) / 2); 使用 show_n_char()只要把我們想要顯示的字元和數量當參數傳進 去,show_n_char()就可以依照它們來顯示 這些不同的寫法,最後做的動作其實都一樣,因為最後其實傳的是 int 值。 像 show_n_char(SPACE, (WIDTH - strlen(PLACE)) / 2); 其實會先把 (WIDTH - strlen(PLACE)) / 2 算出來 得到10,然後把10這個值當參數傳 給show_n_char() show_n_char()並不需要知道外面究竟做了什麼事,只要知道傳進來的第 二個參數的值是 10就夠了。若以 show_n_char(SPACE, spaces); 這個 例子來說,傳進去的也是當時變數 spaces 的值 (值為 7 )。

function 主體 (definition) 的部份則在右上角,用了迴圈來計算次方。 double power(double n, int p) {    double pow = 1;    int i;    for (i = 1; i <= p; i++) { pow *= n;    }    return pow; } #include <stdio.h> double power(double n, int p); int main(void) {    double x, xpow;    int exp;        printf("Enter a number and the positive integer power\n");    printf(" to which the number will be raised. Enter q to quit.\n");    while (scanf("%lf%d", &x, &exp) == 2) {       xpow = power(x, exp);       printf("%.3f to the power %d is %.5f\n", x, exp, xpow);       printf("Enter next pair of numbers or q to quit.\n"); }    printf("\nBye!\n");    return 0; } 宣告 範例3-2 自定的 function取名為 power(),用來計算某個數的整數次方,由宣告可 以看出 power() 要傳入兩個參數,分別是型別為 double 的底數 n 以及型 別為 int 的指數 p。 function 主體 (definition) 的部份則在右上角,用了迴圈來計算次方。 這樣的模組化程式設計方式是我們學習 C 語言要多加練習的重點之一。

黑盒子 把 function 想成一個黑盒子,使用 function 的時候可以不管 它裡面到底怎麼做的,只要確定它可以辦 到我們想要做的事情, 然後知道要傳什麼樣的參數就夠了 由於這種黑盒子的特性,我們不必擔心定義在 function 裡面的 變數是否會和外部的變數衝突 假設 main() 裡面有個變數叫做 x,然後某個 function f() 裡也 有個變數 x, 則更改f() 裡的x並不會改變main()裡的x。 再重複強調一次,當參數傳入 function 時,只有值會被複製傳 入,所以在 function 裡對參數做修改,同樣也是不會影響外部 的變數值

#include <stdio.h> void f(int x); int main(void) {    int x = 1;    printf("main: %d\n", x);    f(x);    return 0; } void f(int x)    x++;    printf("f: %d\n", x); 輸出: main: 1 f: 2 範例3-3 一開始在main()裡面x的值被設為 1 然後把x當參數傳入f(),在 functionf()裡 的 local variable 也叫做 x ,這個 x 因為接收傳入的參數,所以 值也是 1 在 f() 裡做了 x++; 所以 x 的值變成 2,然後 f() 結束回到 main(), 這時 main() 裡的 x 和呼叫 f() 前沒有兩樣,所以值還是 1

Function 程式執行行為

Memory #include <stdio.h> void fun_1(void); void fun_2(int);    int main(void) { fun_1(); printf("goodbye goodbye\n");  return 0; }   void fun_1(void) int imidate=1; fun_2(imidate); printf("goodbye fun_1\n"); void fun_2(int a) int b = a; Memory

Frame for main()  Memory #include <stdio.h> void fun_1(void); void fun_2(int);    int main() { fun_1(); printf("goodbye goodbye\n");  return 0; }   void fun_1(void) int imidate=1; fun_2(imidate); printf("goodbye fun_1\n"); void fun_2(int a) int b = a; Frame for main()  Memory

Frame for main() Frame for fun_1()  Memory #include <stdio.h> void fun_1(void); void fun_2(int);    int main() { fun_1(); printf("goodbye goodbye\n");  return 0; }   void fun_1(void) int imidate=1; fun_2(imidate); printf("goodbye fun_1\n"); void fun_2(int a) int b = a; Frame for main() Frame for fun_1()  Memory

Frame for main() Frame for fun_1() Frame for fun_2()  Memory #include <stdio.h> void fun_1(void); void fun_2(int);    int main() { fun_1(); printf("goodbye goodbye\n");  return 0; }   void fun_1(void) int imidate=1; fun_2(imidate); printf("goodbye fun_1\n"); void fun_2(int a) int b = a; Frame for main() Frame for fun_1() Frame for fun_2()  Memory

Frame for main() Frame for fun_1()  Memory #include <stdio.h> void fun_1(void); void fun_2(int);    int main() { fun_1(); printf("goodbye goodbye\n");  return 0; }   void fun_1(void) int imidate=1; fun_2(imidate); printf("goodbye fun_1\n"); void fun_2(int a) int b = a; Frame for main() Frame for fun_1()  Memory

Frame for main()  Memory #include <stdio.h> void fun_1(void); void fun_2(int);    int main() { fun_1(); printf("goodbye goodbye\n");  return 0; }   void fun_1(void) int imidate=1; fun_2(imidate); printf("goodbye fun_1\n"); void fun_2(int a) int b = a; Frame for main()  Memory

Function 回傳值

#include <stdio.h> int imin(int, int); int main(void) {    int evil1, evil2;    printf("Enter a pair of integers (0 0 to quit): ");    while(scanf("%d %d", &evil1, &evil2) && !(evil1 == 0 && evil2 == 0)) {     printf("The lesser of %d and %d is %d.\n",       evil1, evil2, imin(evil1, evil2));     printf("Enter a pair of integers (0 0 to quit): "); }    printf("Bye.\n");    return 0; int imin(int n, int m)    int min;    if (n < m) { min = n; }    else { min = m; }    return min; 輸出: Enter a pair of integers (0 0 to quit): 300 200 The lesser of 300 and 200 is 200. Enter a pair of integers (0 0 to quit): -8 9 The lesser of -8 and 9 is -8. Enter a pair of integers (0 0 to quit): 0 0 Bye. 範例3-4

輸入兩個整數之後就會用 imin() 來判斷出兩者中較小的數 imin() 的 prototype 宣告成 int imin(int, int); 代表會傳入兩個 int 參數,然後要回傳一個 int。 我們希望回傳值等於傳入參數值中較小的那ㄧ個值,這只要用 if else 就 可以辦到。 在 imin() 的 definition 的最後,必須用 return 把結果傳回 去,在這個範例的寫法就是 return min; 表示要把變數 min 的當時的值 傳回去 在 main() 裡面呼叫 imin(evil1, evil2) 這個 expression 的值會等於 imin() 做完之 後 return 傳回來的值。譬如 imin(5, 3) 的值就等於 3 int imin(int n, int m) {    int min;    if (n < m) { min = n; }    else { min = m; }    return min; }

轉型 由於 what_if() 宣告的回傳值型別是 int 雖然 z 是 double,但是在 return 的時候 會被強制轉成 int int what_if(int n) {     double z = 100.0/ (double) n;     return z; /* what happens? */ } 範例3-5 由於 what_if() 宣告的回傳值型別是 int 雖然 z 是 double,但是在 return 的時候 會被強制轉成 int

return return有一個效果是讓目前的 function 結束,直接跳回到原來呼叫者的 程式碼片段。所以其實return不一定要在程式的最後面 程式最後一行的 printf() 永遠不會被執行。 如果 function 的不需要回傳值 (也就是宣告成 void),那麼也可以用 return; 讓 function 在中途跳回去,寫法就是 return 直接加分號 ; 不傳 回任何值 (因為是 void),只讓 function就此結束執行。 int imin(int n, int m) {    if (n < m)       return n;    else       return m;    printf("You can't see me.\n"); } 範例3-6 void show_postive(int x) {    if (x < 0)       return;    else       printf("%d\n", x); } 範例3-7

Main

#include <stdio.h> int main(void) /* display an integer on screen */ {     int num;     num = 40;     printf("The number is %d.\n", num);     return 0; } 範例3-8 C 程式可以看成是許多 functions 的集合 每個 function 會負責某項工作,依照輸入的參數對資料作處理, 然後將結果傳 回 其中最重要的而且一定要包含的 function 就是 main(),它是你的程式的進入點 當你的程式開始執行時,首先就會執行main(),然後在main()裡面再去呼叫其他 functions 在 main() 前面的 int 表示 main() 結束後回傳值 (return value) 的型別是 int, 也就是整數 (integer) 在括號中的 void 表示這個程式的main()在呼叫時不需要傳入任何參數

main的回傳值通常做為判別程式是否正常執行的error code 慣例上,0代表正常,非0的數字代表錯誤或某個狀態 #include <stdio.h> int main(void) /* display an integer on screen */ {     int num;     num = 40;     printf("The number is %d.\n", num);     return 0; } main的回傳值通常做為判別程式是否正常執行的error code 慣例上,0代表正常,非0的數字代表錯誤或某個狀態

> ./3-8.exe first second abc main的參數有兩種 void int argc, char * argv[] argc: 紀錄參數的數量 argv: 儲存了每個參數的字串 在console中執行: > ./3-8.exe first second abc 輸出: number of arguments = 4 argv[0] = ./3-8.exe argv[1] = first argv[2] = second argv[3] = abc #include <stdio.h> int main(int argc, char* argv[]) {     int i; printf("number of arguments = %d\n", argc); for(i = 0; i < argc; i++) {      printf("argv[i] = %s\n", argv[i]); }     return 0; 範例3-9

exit 在stdlib.h中有個函式exit,效果是直接離開程式 void exit (int status); status跟main function的return value同義 預設有define EXIT_SUCCESS, EXIT_FAILURE兩個常數 可以在function中呼叫exit,直接結束程式 #include <stdio.h> #include <stdlib.h> void one_or_exit(int x) {    if (x == 1)       return;    else       exit(EXIT_FAILURE); } int main(void)     int i; one_or_exit(0);     return 0;

Scope

Local & Global 依照變數的有效或可見範圍,我們可以把它們劃分成 local variables 和 global variables local:定義在 function 裡面 的變數只有那個 function 可以看得到 global:定義在整個程式最前面,在所有 functions 外面的變數,則是全 部的 functions 都看得到 在命名方面,同一個 scope 裡同一個名字當然不能用兩次譬如 int a; double a; 但是在 function 裡的 local variable 可以和 global variable 同名,這種 情況global variable 在那個 function 裡面會被當作不存在。

上面的例子顯示了變數存在於記憶體的時間長短。 #include <stdio.h> int aa = 100; void f(void) {     int aa = 3;     printf("f: %d\n", aa++); } int main(void)     printf("main: %d\n", aa++);     f();     return 0; 輸出: main: 100 f: 3 main: 101 範例3-10 上面的例子顯示了變數存在於記憶體的時間長短。 local variables 只有當 function 被呼叫的時候才會自動出現在記憶體 (stack) 中,而當 function 結束後就不見。 global variables 則是在整個程式執行過程都會一直存在。

static 如何讓 Function 裡面的變數一直存在? 就是在變數的型別前面加上 static 輸出: main: 100 f: 3 如果你想持續記錄某些資料,但是又不想像 global variables 一樣可以 被全部的 functions 隨意修改,就可以用 static variables,只透過某個特 定的 function 來修改。 #include <stdio.h> int aa = 100; int f(void) {     static int aa = 3;     printf("f: %d\n", aa++);     return aa; } int main(void)     printf("main: %d\n", aa++);     f();     return 0 ; 輸出: main: 100 f: 3 main: 101 f: 4 範例3-11

static (cont.) static global variable & static function 當在一個全域變數或是function的宣告前面加上static,就可以將它 的有效範圍限制在這份程式碼內,也就是有多份程式碼一起編譯時, 存在於其他檔案中的程式無法存取這個變數/function。 static void call() {     add(1, 1); } #include <stdio.h> static int add(int a, int b) {     return a + b; } int main(void)     printf(“1 + 1 = %d\n", add(1, 1)); call();     return 0 ; another.c 範例3-12 main.c 編譯失敗

extern 在一個變數宣告前加上extern,聲明此變數在其他位置(檔案) 被定義。 #include <stdio.h> static int add(int a, int b) {     return a + b; } int main(void)     extern int a; printf("a = %d", a);     return 0 ; int a = 100; another.c 輸出: a = 100 範例3-13 main.c

Appendix

參數列輸入(argc, argv) 要使用參數列輸入,需要在命令提示字元下執行 開始->所有程式->附屬應用程式->命令提示字元 以拖拉方式將程式路徑填入命令提示字元 在路徑後面即可寫入需要的參數

參數列輸入(argc, argv) 以範例3-9為例