C Program Design Functions and Program Structure 主講人:虞台文

Preview:

Citation preview

C Program DesignFunctions and Program Structure

主講人:虞台文

Content Introduction Function Definitions void Functions Formal Parameters and Actual Parameters Return Statements Call-by-Value and Call-by-Reference Array Parameters Multiple Source Files and Headers String Functions Storage Classes Global/Local Variables Extern Variables Static Variables Recursion

C Program DesignFunctions and Program Structure

Introduction

Divide & Conquer

Construct a program from smaller pieces or components– These smaller pieces are called modules

Each piece more manageable than the original program

Functions

Modules in C– Programs combine user-defined functions

with library functions

C standard library has a wide variety of functions

Function Calls

Function Calls Function invocation

– Provide function name and arguments (data)– Function performs operations or manipulations– Function returns results

Real-life analogy:– Boss asks a specialist to complete a specific task– The specialist gets information, does the task– The specialist returns the result

Information hiding: – Caller (boss) does not know details

Benefits of Functions

Divide and conquer– Manageable program development

Software reusability– Use existing functions as building blocks for

new programs– Abstraction - hide internal details

Avoid code repetition

Good Programming Practices

Familiarize yourself with the rich collection of functions in the C Standard Library.

Avoid reinventing the wheel. – When possible, use C Standard Library functions

instead of writing new functions.– This can reduce program development time.

Using the functions in the C Standard Library helps make programs more portable.

Some Library Functions

C Standard Library

C Stdio Library

C Math Library

C Stdlib Library

C Time Library

Using Library Functions

#include <stdio.h> // printf() and scanf() defined#include <math.h> // sqrt() defined

main(){ double a, b;

printf("Enter two legs a and b of a right triangle:"); scanf("%lf%lf",&a,&b);

printf("The hypotenuse c of the triangle is %10.5lf\n", sqrt(a * a + b * b));}

#include <stdio.h> // printf() and scanf() defined#include <math.h> // sqrt() defined

main(){ double a, b;

printf("Enter two legs a and b of a right triangle:"); scanf("%lf%lf",&a,&b);

printf("The hypotenuse c of the triangle is %10.5lf\n", sqrt(a * a + b * b));}

畢氏定理 (Pythagorean theorem )

a2 + b2 = c2

printf

printf

scanf

sqrt

範例:亂數產生器#include <stdio.h> // printf() defined#include <stdlib.h> // srand(), rand() defined#include <time.h> // time() defined

main(){ int i;

/* Seed the random-number generator with current time so that * the numbers will be different every time we run. */ srand( (unsigned) time( NULL ) );

/* Display 10 numbers. */ for( i = 0; i < 10;i++ ) printf( " %6d\n", rand() );}

#include <stdio.h> // printf() defined#include <stdlib.h> // srand(), rand() defined#include <time.h> // time() defined

main(){ int i;

/* Seed the random-number generator with current time so that * the numbers will be different every time we run. */ srand( (unsigned) time( NULL ) );

/* Display 10 numbers. */ for( i = 0; i < 10;i++ ) printf( " %6d\n", rand() );}

srand

rand

time

練習 :[5.28]

1. Write a program that simulates coin tossing. For each toss

of the coin the program should print Heads or Tails. Let the

program toss the coin 100 times, and count the number of

times each side of coin appears. Print the results. The

program should call a separate function flip that takes no

arguments and returns 0 for tails and 1 for heads. [Note: If

the program realistically simulates the coin tossing, then

each side of the coin should appear approximately half the

time for a total of approximately 50 heads and 50 tails.]

練習 :[5.32]2. Write a C program that plays the game of “guess the number” as

follows: Your program chooses the number to be guessed by selecting an integer at random in the range 1 to 1000. The program then types:I have a number between 1 and 1000.Can you guess my number?Please type your first guess.

The player then types a first guess. The program responds with one of the following:a) Excellent! You guessed the number!

Would you like to play again (y or n)?b) Too low. Try again.c) Too high. Try again.

If the player’s guess in incorrect, your program should loop until the player finally gets the number right. Your program should keep telling the player too high or too low to help the player “zero in” on the correct answer.

C Program DesignFunctions and Program Structure

Function

Definitions

Function Definitions

return-type function-name( parameter-list )

{

declarations

statements

}

Function body (the detail)

Function Definitions

return-type function-name( parameter-list )

{

declarations

statements

}

Function body (the detail)

any valid identifier

any valid identifier

data type of the result (default int)void – indicates that the function returns nothing

data type of the result (default int)void – indicates that the function returns nothing

comma separated list, declares parameters

comma separated list, declares parameters

範例:#include <stdio.h>

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

#include <stdio.h>

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

範例:#include <stdio.h>

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

#include <stdio.h>

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

範例:#include <stdio.h>

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

#include <stdio.h>

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

double ctof(double)

double average(double, int)

int main()

Uses ctof and average

此三函式次序可否任意對調?此三函式次序可否任意對調?

範例:#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

範例:#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

範例:#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

範例:#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

範例:#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

double ctof(double); // prototypedouble average(double, int); // prototype

範例:#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum=0; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(double, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

double ctof(); // prototypedouble average(); // prototype

練習:1. 重新製作一 C程式將以上範例中,華氏與攝氏的角色互換。

2. 製作一方便操作之程式進行MKS制 (公制 )與 FPS制 (英制 )間之單位轉換。參考網址

C Program DesignData Types

void

Functions

void Functions

不傳回任何值之函式,即所謂的 Procedures.

範例:#include <stdio.h>

// forward referencesint readline(char[]); // prototypevoid welcome(char[]); // prototype

#define MAX_LINE 100char userName[MAX_LINE]; // buffer for user name

main(){ printf("Please enter your name: "); readline(userName); // ignore returned value welcome(userName); // say hello to login user // ...........................}

int readline(char strBuffer[]) { int c, count=0; while((c=getchar()) != '\n') strBuffer[count++] = c; strBuffer[count] = '\0';  // null terminated return count; // #char in the line}

void welcome(char name[]){ printf("%s, you are welcome.\n", name);}

#include <stdio.h>

// forward referencesint readline(char[]); // prototypevoid welcome(char[]); // prototype

#define MAX_LINE 100char userName[MAX_LINE]; // buffer for user name

main(){ printf("Please enter your name: "); readline(userName); // ignore returned value welcome(userName); // say hello to login user // ...........................}

int readline(char strBuffer[]) { int c, count=0; while((c=getchar()) != '\n') strBuffer[count++] = c; strBuffer[count] = '\0';  // null terminated return count; // #char in the line}

void welcome(char name[]){ printf("%s, you are welcome.\n", name);}

用戶輸入姓名登入後,出現歡迎訊息。

用戶輸入姓名登入後,出現歡迎訊息。

範例:#include <stdio.h>

// forward referencesint readline(char[]); // prototypevoid welcome(char[]); // prototype

#define MAX_LINE 100char userName[MAX_LINE]; // buffer for user name

main(){ printf("Please enter your name: "); readline(userName); // ignore returned value welcome(userName); // say hello to login user // ...........................}

int readline(char strBuffer[]) { int c, count=0; while((c=getchar()) != '\n') strBuffer[count++] = c; strBuffer[count] = '\0';  // null terminated return count; // #char in the line}

void welcome(char name[]){ printf("%s, you are welcome.\n", name);}

#include <stdio.h>

// forward referencesint readline(char[]); // prototypevoid welcome(char[]); // prototype

#define MAX_LINE 100char userName[MAX_LINE]; // buffer for user name

main(){ printf("Please enter your name: "); readline(userName); // ignore returned value welcome(userName); // say hello to login user // ...........................}

int readline(char strBuffer[]) { int c, count=0; while((c=getchar()) != '\n') strBuffer[count++] = c; strBuffer[count] = '\0';  // null terminated return count; // #char in the line}

void welcome(char name[]){ printf("%s, you are welcome.\n", name);}

用戶輸入姓名登入後,出現歡迎訊息。

用戶輸入姓名登入後,出現歡迎訊息。

範例:#include <stdio.h>

// forward referencesint readline(char[]); // prototypevoid welcome(char[]); // prototype

#define MAX_LINE 100char userName[MAX_LINE]; // buffer for user name

main(){ printf("Please enter your name: "); readline(userName); // ignore returned value welcome(userName); // say hello to login user // ...........................}

int readline(char strBuffer[]) { int c, count=0; while((c=getchar()) != '\n') strBuffer[count++] = c; strBuffer[count] = '\0';  // null terminated return count; // #char in the line}

void welcome(char name[]){ printf("%s, you are welcome.\n", name);}

#include <stdio.h>

// forward referencesint readline(char[]); // prototypevoid welcome(char[]); // prototype

#define MAX_LINE 100char userName[MAX_LINE]; // buffer for user name

main(){ printf("Please enter your name: "); readline(userName); // ignore returned value welcome(userName); // say hello to login user // ...........................}

int readline(char strBuffer[]) { int c, count=0; while((c=getchar()) != '\n') strBuffer[count++] = c; strBuffer[count] = '\0';  // null terminated return count; // #char in the line}

void welcome(char name[]){ printf("%s, you are welcome.\n", name);}

用戶輸入姓名登入後,出現歡迎訊息。

用戶輸入姓名登入後,出現歡迎訊息。

readline()函式有何風險?

練習1. 執行以上程式,輸入過長之字串,觀察結果。

2. 將 readline之 prototype重新定義為:

其中 maxbuf表示 buffer的大小。

3. 更改範例程式使用新定義之 readline函式,檢視overflow現象是否解除 ?

int readline(char strBuffer[], int maxbuf);

練習4. Write a function void beep(int n) whi

ch emits n audio beeps.

C Program DesignFunctions and Program Structure

Actual Parameters and

Formal Parameters

Formal Parameters and Actual Parameters

Formal parameters are parameters as they appear in function declarations.

Actual parameters are parameters as they appear in function calls.

範例:#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(int, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

#include <stdio.h>// forward referencesdouble ctof(double celsius); // prototypedouble average(double total, int count); // prototype

main() // in fact it is int main( void ){ double temperature; double faren, avg, sum; int counter = 0;

while (counter < 10) { counter++; printf ("Please enter temperature %d in Celsius: ", counter); scanf("%lf",&temperature); faren = ctof(temperature); // call ctof(double) printf ("result: %.2lf C = %.2lf F\n", temperature, faren); sum += faren; }

avg = average(sum, counter); // call average(int, int) printf ("average was %.2lf F\n",avg);

return 0; // C compiler doesn’t check the existence of return}

double ctof(double celsius) { double result; result = celsius * 9.0 / 5.0 + 32.0; return result;}

double average(double total, int count){ return (total / (double) count);}

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

輸入十個攝氏溫度,將之轉換成華氏溫度後求其平均。

Formal ParametersFormal Parameters

Actual Parameters

Actual Parameters

Type Conversion Parameter Passing

#include <stdio.h>// missing forward references

main(){ int v1, v2, v3, v4;

v1 = fun(); v2 = fun(2); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(int a){ return 2 * a;}

#include <stdio.h>// missing forward references

main(){ int v1, v2, v3, v4;

v1 = fun(); v2 = fun(2); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(int a){ return 2 * a;}

Type Conversion Parameter Passing

#include <stdio.h>// missing forward references

main(){ int v1, v2, v3, v4;

v1 = fun(); v2 = fun(2); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(int a){ return 2 * a;}

#include <stdio.h>// missing forward references

main(){ int v1, v2, v3, v4;

v1 = fun(); v2 = fun(2); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(int a){ return 2 * a;}

Type Conversion Parameter Passing

#include <stdio.h>// forward referencesint fun(int); // prototypes

main(){ int v1, v2, v3, v4;

v1 = fun(); v2 = fun(2); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(int a){ return 2 * a;}

#include <stdio.h>// forward referencesint fun(int); // prototypes

main(){ int v1, v2, v3, v4;

v1 = fun(); v2 = fun(2); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(int a){ return 2 * a;}

Type Conversion Parameter Passing

#include <stdio.h>// forward referencesint fun(int); // prototypes

main(){ int v1, v2, v3, v4;

v1 = fun(); v2 = fun(2); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(int a){ return 2 * a;}

#include <stdio.h>// forward referencesint fun(int); // prototypes

main(){ int v1, v2, v3, v4;

v1 = fun(); v2 = fun(2); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(int a){ return 2 * a;}

Type Conversion Parameter Passing

#include <stdio.h>// forward referencesint fun(int); // prototypes

main(){ int v1, v2, v3, v4;

v1 = fun(2.0); v2 = fun(2); v3 = fun(2.5); v4 = fun1(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(int a){ return 2 * a;}

#include <stdio.h>// forward referencesint fun(int); // prototypes

main(){ int v1, v2, v3, v4;

v1 = fun(2.0); v2 = fun(2); v3 = fun(2.5); v4 = fun1(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(int a){ return 2 * a;}

Type Conversion Parameter Passing

#include <stdio.h>// missing forward references

main(){ int v1, v2, v3, v4;

v1 = fun(2); v2 = fun(2.0); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(double a){ return 2 * a;}

#include <stdio.h>// missing forward references

main(){ int v1, v2, v3, v4;

v1 = fun(2); v2 = fun(2.0); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(double a){ return 2 * a;}

Type Conversion Parameter Passing

#include <stdio.h>// forward referencesint fun(double); // prototypes

main(){ int v1, v2, v3, v4;

v1 = fun(2); v2 = fun(2.0); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(double a){ return 2 * a;}

#include <stdio.h>// forward referencesint fun(double); // prototypes

main(){ int v1, v2, v3, v4;

v1 = fun(2); v2 = fun(2.0); v3 = fun(2.5); v4 = fun(2.5, 3);

printf("v1 = %d\nv2 = %d\nv3 = %d\nv4 = %d\n", v1, v2, v3, v4);}

int fun(double a){ return 2 * a;}

C Program DesignFunctions and Program Structure

Return Statements

Return Statement

return expressionConversion will be

performed if necessary(can be absent)

Function returns to the caller immediately• after executing a return statement; or• no statement remained to be executed.

More on Return Statement

The return statement terminates the execution of the function body and passes control to the caller.

The caller is free to ignore the returned value.

Missing return statement, though improper in some cases, is not illegal– In this case, result is unpredictable

範例:

#include <stdio.h>

int fun1(int), fun2(int), fun3(int), fun4(int);

int main(){ int m, n, o, p, q; fun1(3.0); /* caller ignores the return value */ m = fun1(2.0); /* m = 4 parameter converted to int before calling */ n = fun2(2); /* n = 1 */ o = fun2(-2); /* o = ? */ p = fun3(2); /* p = ? */ q = fun4(2); /* q = ? */ printf("m=%d\nn=%d\no=%d\np=%d\nq=%d\n", m, n, o, p, q); /* main don’t return any value */}

int fun1(int a){ return 2.0 * a; /* converted to integer before return */}

int fun2(int a){ if(a > 0) return 1; /* return nothing when a <= 0 */}

int fun3(int a){ return; /* missing expression */}

int fun4(int a){ /* do nothing */}

#include <stdio.h>

int fun1(int), fun2(int), fun3(int), fun4(int);

int main(){ int m, n, o, p, q; fun1(3.0); /* caller ignores the return value */ m = fun1(2.0); /* m = 4 parameter converted to int before calling */ n = fun2(2); /* n = 1 */ o = fun2(-2); /* o = ? */ p = fun3(2); /* p = ? */ q = fun4(2); /* q = ? */ printf("m=%d\nn=%d\no=%d\np=%d\nq=%d\n", m, n, o, p, q); /* main don’t return any value */}

int fun1(int a){ return 2.0 * a; /* converted to integer before return */}

int fun2(int a){ if(a > 0) return 1; /* return nothing when a <= 0 */}

int fun3(int a){ return; /* missing expression */}

int fun4(int a){ /* do nothing */}

範例:

#include <stdio.h>

int fun1(int), fun2(int), fun3(int), fun4(int);

int main(){ int m, n, o, p, q; fun1(3.0); /* caller ignores the return value */ m = fun1(2.0); /* m = 4 parameter converted to int before calling */ n = fun2(2); /* n = 1 */ o = fun2(-2); /* o = ? */ p = fun3(2); /* p = ? */ q = fun4(2); /* q = ? */ printf("m=%d\nn=%d\no=%d\np=%d\nq=%d\n", m, n, o, p, q); /* main don’t return any value */}

int fun1(int a){ return 2.0 * a; /* converted to integer before return */}

int fun2(int a){ if(a > 0) return 1; /* return nothing when a <= 0 */}

int fun3(int a){ return; /* missing expression */}

int fun4(int a){ /* do nothing */}

#include <stdio.h>

int fun1(int), fun2(int), fun3(int), fun4(int);

int main(){ int m, n, o, p, q; fun1(3.0); /* caller ignores the return value */ m = fun1(2.0); /* m = 4 parameter converted to int before calling */ n = fun2(2); /* n = 1 */ o = fun2(-2); /* o = ? */ p = fun3(2); /* p = ? */ q = fun4(2); /* q = ? */ printf("m=%d\nn=%d\no=%d\np=%d\nq=%d\n", m, n, o, p, q); /* main don’t return any value */}

int fun1(int a){ return 2.0 * a; /* converted to integer before return */}

int fun2(int a){ if(a > 0) return 1; /* return nothing when a <= 0 */}

int fun3(int a){ return; /* missing expression */}

int fun4(int a){ /* do nothing */}

C Program DesignFunctions and Program Structure

Call-by-Valueand

Call-by-Reference

範例 : Power#include <stdio.h>int power(int m, int n);

main(){ int n, val;

n = 5; val = power(2, n); printf("val=%d n=%d\n", val, n);}

/* power: raise base to n-th power; n >= 0 */int power(int base, int n){ int result;

for (result = 1; n > 0; --n) result *= base; return result;}

#include <stdio.h>int power(int m, int n);

main(){ int n, val;

n = 5; val = power(2, n); printf("val=%d n=%d\n", val, n);}

/* power: raise base to n-th power; n >= 0 */int power(int base, int n){ int result;

for (result = 1; n > 0; --n) result *= base; return result;}

n=?n=?

Call-by-Value vs. Call-by-Reference

Call by value– Copy of argument passed to function– Changes in function do not effect original– Use when function does not need to modify argument

Avoids accidental changes

Call by reference – Passes original argument (in fact, the argument’s

address)– Changes in function effect original– Only used with trusted functions

C only has call-by-value.

C++ has both.

C Program DesignFunctions and Program Structure

Array Parameters

Call by Value

In C, all function arguments are passed “by value.”

– the called function is given the values of its arguments in

temporary variables rather than the originals.

– Modifying the values of formal parameters doesn’t effect

the value of originals

How about if a function has arrays (big objects) as

its parameters?

範例 #include <stdio.h>

void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

void RemoveFactor5(int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % 5 == 0 && vals[i] > 0) vals[i] /= 5;}

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactor5(data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

#include <stdio.h>

void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

void RemoveFactor5(int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % 5 == 0 && vals[i] > 0) vals[i] /= 5;}

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactor5(data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

將一正整數陣列中之各元素移除因子 5

將一正整數陣列中之各元素移除因子 5

範例 #include <stdio.h>

void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

void RemoveFactor5(int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % 5 == 0 && vals[i] > 0) vals[i] /= 5;}

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactor5(data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

#include <stdio.h>

void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

void RemoveFactor5(int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % 5 == 0 && vals[i] > 0) vals[i] /= 5;}

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactor5(data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

將一正整數陣列中之各元素移除因子 5

將一正整數陣列中之各元素移除因子 5

Declaring array as a function’s argument.

Declaring array as a function’s argument.

Passing array argument to a function by writing

its name.

Passing array argument to a function by writing

its name.

const qualifier tells compiler that array cannot be changedconst qualifier tells compiler that array cannot be changed

範例 #include <stdio.h>

void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

void RemoveFactor5(int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % 5 == 0 && vals[i] > 0) vals[i] /= 5;}

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactor5(data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

#include <stdio.h>

void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

void RemoveFactor5(int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % 5 == 0 && vals[i] > 0) vals[i] /= 5;}

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactor5(data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

將一正整數陣列中之各元素移除因子 5

將一正整數陣列中之各元素移除因子 5

Declaring Function’s Prototype w/ Array Arguments

void listElements(const int vals[], int size);

void RemoveFactor5(int vals[], int size);

void listElements(const int[], int);

void RemoveFactor5(int[], int);

範例#include <stdio.h>

void listElements(const int[], int);void RemoveFactor5(int[], int);

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactor5(data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

void RemoveFactor5(int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % 5 == 0 && vals[i] > 0) vals[i] /= 5;}

#include <stdio.h>

void listElements(const int[], int);void RemoveFactor5(int[], int);

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactor5(data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

void RemoveFactor5(int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % 5 == 0 && vals[i] > 0) vals[i] /= 5;}

將一正整數陣列中之各元素移除因子 5

將一正整數陣列中之各元素移除因子 5

C Program DesignFunctions and Program Structure

Multiple Source Files

and Headers

Headers Header files for C Standard Library

– Contain function prototypes for library functions– <stdlib.h>, <math.h> , etc– Load with #include <filename>

#include <math.h>

Custom header files– Create file with functions – Save as filename.h– Load in other files with #include "filename.h"– Reuse functions

範例/* IntFunctions.c */#include <stdio.h>

/* print an int array’s elements separated by space */void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

/* remove factor n from all elements in an int array */void RemoveFactorn(int n, int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % n == 0 && vals[i] > 0) vals[i] /= n;}

/* IntFunctions.c */#include <stdio.h>

/* print an int array’s elements separated by space */void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

/* remove factor n from all elements in an int array */void RemoveFactorn(int n, int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % n == 0 && vals[i] > 0) vals[i] /= n;}

/* IntFunctions.h */

void listElements(const int[], int);void RemoveFactorn(int, int[], int);

/* IntFunctions.h */

void listElements(const int[], int);void RemoveFactorn(int, int[], int);

範例 /* IntFunctions.h */

void listElements(const int[], int);void RemoveFactorn(int, int[], int);

/* IntFunctions.h */

void listElements(const int[], int);void RemoveFactorn(int, int[], int);

/* main.c */#include <stdio.h>#include "IntFunctions.h"

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactorn(5, data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

/* main.c */#include <stdio.h>#include "IntFunctions.h"

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactorn(5, data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

/* IntFunctions.h */

void listElements(const int[], int);void RemoveFactorn(int, int[], int);

/* IntFunctions.h */

void listElements(const int[], int);void RemoveFactorn(int, int[], int);

範例 : Multiple Source Files

/* IntFunctions.c */#include <stdio.h>

/* print an int array’s elements separated by space */void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

/* remove factor n from all elements in an int array */void RemoveFactorn(int n, int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % n == 0 && vals[i] > 0) vals[i] /= n;}

/* IntFunctions.c */#include <stdio.h>

/* print an int array’s elements separated by space */void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

/* remove factor n from all elements in an int array */void RemoveFactorn(int n, int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % n == 0 && vals[i] > 0) vals[i] /= n;}

/* main.c */#include <stdio.h>#include "IntFunctions.h"

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactorn(5, data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

/* main.c */#include <stdio.h>#include "IntFunctions.h"

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactorn(5, data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

/* IntFunctions.h */

void listElements(const int[], int);void RemoveFactorn(int, int[], int);

/* IntFunctions.h */

void listElements(const int[], int);void RemoveFactorn(int, int[], int);

範例 : Multiple Source Files

/* IntFunctions.c */#include <stdio.h>

/* print an int array’s elements separated by space */void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

/* remove factor n from all elements in an int array */void RemoveFactorn(int n, int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % n == 0 && vals[i] > 0) vals[i] /= n;}

/* IntFunctions.c */#include <stdio.h>

/* print an int array’s elements separated by space */void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

/* remove factor n from all elements in an int array */void RemoveFactorn(int n, int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % n == 0 && vals[i] > 0) vals[i] /= n;}

/* main.c */#include <stdio.h>#include "IntFunctions.h"

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactorn(5, data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

/* main.c */#include <stdio.h>#include "IntFunctions.h"

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactorn(5, data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

/* IntFunctions.h */

void listElements(const int[], int);void RemoveFactorn(int, int[], int);

/* IntFunctions.h */

void listElements(const int[], int);void RemoveFactorn(int, int[], int);

範例 : Multiple Source Files

/* IntFunctions.c */#include <stdio.h>

/* print an int array’s elements separated by space */void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

/* remove factor n from all elements in an int array */void RemoveFactorn(int n, int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % n == 0 && vals[i] > 0) vals[i] /= n;}

/* IntFunctions.c */#include <stdio.h>

/* print an int array’s elements separated by space */void listElements(const int vals[], int size){ int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);}

/* remove factor n from all elements in an int array */void RemoveFactorn(int n, int vals[], int size){ int i;

for(i=0; i<size; i++) while(vals[i] % n == 0 && vals[i] > 0) vals[i] /= n;}

/* main.c */#include <stdio.h>#include "IntFunctions.h"

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactorn(5, data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

/* main.c */#include <stdio.h>#include "IntFunctions.h"

main(){ int data[]={12, 55, 6, 21, 35, 90, 91};

printf("Original elements in data[] are: \n"); listElements(data, sizeof(data)/sizeof(int));

RemoveFactorn(5, data, sizeof(data)/sizeof(int));

printf("\n\nRemoving factor 5, elements in data[] become:\n"); listElements(data, sizeof(data)/sizeof(int)); printf("\n");}

Practice the operations in IDE by yourselves.

C Program DesignFunctions and Program Structure

String Functions

Strings in C Null-terminated string In C, a string is stored as an array

of characters containing the characters in the string and terminated with a '\0' to mark the end.

char str[]="hello\n";

Example: h (68)

e (65)

l (6C)

l (6C)

o (6F)

\n (0A)

\0 (00)

str str[0]

str[1]

str[2]

str[3]

str[4]

str[5]

str[6]

sizeof(str) = 7

Strings in CASCII

範例 : Print the Longest Line

while (there's another line)

if (it's longer than the previous longest)

(save it)

(save its length)

print longest line

while (there's another line)

if (it's longer than the previous longest)

(save it)

(save its length)

print longest line

範例 : Print the Longest Line

while (there's another line)

if (it's longer than the previous longest)

(save it)

(save its length)

print longest line

while (there's another line)

if (it's longer than the previous longest)

(save it)

(save its length)

print longest line

Implement a getline() function which returns the length of the line read.

Implement a getline() function which returns the length of the line read.

Implement a copy() function to save string.

Implement a copy() function to save string.

範例 : Print the Longest Line

/* getline: read a line into s, return length */int getline(char s[],int lim){ int c, i;

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)s[i] = c;

if (c == '\n') { s[i] = c; ++i; } s[i] = '\0'; return i;}

/* getline: read a line into s, return length */int getline(char s[],int lim){ int c, i;

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)s[i] = c;

if (c == '\n') { s[i] = c; ++i; } s[i] = '\0'; return i;}

範例 : Print the Longest Line

/* getline: read a line into s, return length */int getline(char s[],int lim){ int c, i;

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)s[i] = c;

if (c == '\n') { s[i] = c; ++i; } s[i] = '\0'; return i;}

/* getline: read a line into s, return length */int getline(char s[],int lim){ int c, i;

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)s[i] = c;

if (c == '\n') { s[i] = c; ++i; } s[i] = '\0'; return i;}

Simplification

s[i++] = c;

s[i++] = c;

範例 : Print the Longest Line

/* getline: read a line into s, return length *//* simplified version */int getline(char s[],int lim){ int c, i;

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n';) s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i;}

/* getline: read a line into s, return length *//* simplified version */int getline(char s[],int lim){ int c, i;

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n';) s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i;}

範例 : Print the Longest Line

/* copy: copy 'from' into 'to'; assume to is big enough */

void copy(char to[], const char from[])

{

int i;

i = 0;

while ((to[i] = from[i]) != '\0') ++i;

}

/* copy: copy 'from' into 'to'; assume to is big enough */

void copy(char to[], const char from[])

{

int i;

i = 0;

while ((to[i] = from[i]) != '\0') ++i;

}

範例 : Print the Longest Line

#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int maxline);void copy(char to[], const char from[]);

/* print the longest input line */main(){ int len; /* current line length */ int max; /* maximum length seen so far */ char line[MAXLINE]; /* current input line */ char longest[MAXLINE]; /* longest line saved here */

max = 0; while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len; copy(longest, line); } if (max > 0) /* there was a line */ printf("%s", longest); return 0;}. . . . . . . . . . . .

#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int maxline);void copy(char to[], const char from[]);

/* print the longest input line */main(){ int len; /* current line length */ int max; /* maximum length seen so far */ char line[MAXLINE]; /* current input line */ char longest[MAXLINE]; /* longest line saved here */

max = 0; while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len; copy(longest, line); } if (max > 0) /* there was a line */ printf("%s", longest); return 0;}. . . . . . . . . . . .

範例 : Print the Longest Line

範例 : Print the Longest Line

範例 : Print the Longest Line

練習1. Write a C function which returns the length of a g

iven string. The length of a string doesn’t include the null character. The function’s prototype is:

int stringLength(char[]);

You may need this function in the next exercise.

練習2. Suppose that you are given two strings, say, string1 and

string2. Write a function which determines whether string2 is a substring of string1. If true, the function returns the position of the first occurrence of string2 in string1. Otherwise, the function returns -1.

For example, if string1 = "I am a boy." and s

tring2 = "a bo", the function returns 5. However, if string2 = "a co", the function returns -1.

Define the function’s prototype properly, and write a program to verify the function’s code.

C Program DesignFunctions and Program Structure

Storage Classes

Global/Local Variables

Global/Local Variables

Global (External) Variables– defined outside any functions– Scoping rule: accessible by any functions visible (some

rules apply)– created (existent) when the program runs, and

destroyed when the program terminates.

Local (Private, Automatic) Variables– defined within the “top” (C++ is more flexible) of a

function or a block statement– scoping rule: accessible only by the function or by the

block which defines them– existent (existent) when the function is called, and

destroyed when the function returns.

範例:

#include <stdio.h>

// declaration of global variablesint data[]={12, 24, 36, 48, 84, 63, 42, 21}; // databaseint numRecords = sizeof(data)/sizeof(int); // #records

// find record in the database using a key// if existent, return its index; otherwise, return -1int linearSearch(int key){ int index = 0; // local variable

while(index < numRecords) if(data[index] == key) return index; else index++;

return -1; // reach here if no record found}

int main(){ int id, index; // local variables

printf("Enter an id: "); scanf("%d", &id); index = linearSearch(id); if(index >= 0) printf("Data found in entry %d with id=%d.\n", index, id); else printf("Data inexistent with id=%d.\n", id);}

#include <stdio.h>

// declaration of global variablesint data[]={12, 24, 36, 48, 84, 63, 42, 21}; // databaseint numRecords = sizeof(data)/sizeof(int); // #records

// find record in the database using a key// if existent, return its index; otherwise, return -1int linearSearch(int key){ int index = 0; // local variable

while(index < numRecords) if(data[index] == key) return index; else index++;

return -1; // reach here if no record found}

int main(){ int id, index; // local variables

printf("Enter an id: "); scanf("%d", &id); index = linearSearch(id); if(index >= 0) printf("Data found in entry %d with id=%d.\n", index, id); else printf("Data inexistent with id=%d.\n", id);}

於資料庫中搜尋是否存在某一 ID之記錄

於資料庫中搜尋是否存在某一 ID之記錄

範例:

#include <stdio.h>

// declaration of global variablesint data[]={12, 24, 36, 48, 84, 63, 42, 21}; // databaseint numRecords = sizeof(data)/sizeof(int); // #records

// find record in the database using a key// if existent, return its index; otherwise, return -1int linearSearch(int key){ int index = 0; // local variable

while(index < numRecords) if(data[index] == key) return index; else index++;

return -1; // reach here if no record found}

int main(){ int id, index; // local variables

printf("Enter an id: "); scanf("%d", &id); index = linearSearch(id); if(index >= 0) printf("Data found in entry %d with id=%d.\n", index, id); else printf("Data inexistent with id=%d.\n", id);}

#include <stdio.h>

// declaration of global variablesint data[]={12, 24, 36, 48, 84, 63, 42, 21}; // databaseint numRecords = sizeof(data)/sizeof(int); // #records

// find record in the database using a key// if existent, return its index; otherwise, return -1int linearSearch(int key){ int index = 0; // local variable

while(index < numRecords) if(data[index] == key) return index; else index++;

return -1; // reach here if no record found}

int main(){ int id, index; // local variables

printf("Enter an id: "); scanf("%d", &id); index = linearSearch(id); if(index >= 0) printf("Data found in entry %d with id=%d.\n", index, id); else printf("Data inexistent with id=%d.\n", id);}

於資料庫中搜尋是否存在某一 ID之記錄

於資料庫中搜尋是否存在某一 ID之記錄

範例: Scope Rule

#include <stdio.h>

int i=0, j=1, k=2;

main(){ int i=3;

printf("1: i=%d, j=%d, k=%d\n", i, j, k);

{ int i=4, j=5;

k = 6; printf("2: i=%d, j=%d, k=%d\n", i, j, k); }

printf("3: i=%d, j=%d, k=%d\n", i, j, k);}

#include <stdio.h>

int i=0, j=1, k=2;

main(){ int i=3;

printf("1: i=%d, j=%d, k=%d\n", i, j, k);

{ int i=4, j=5;

k = 6; printf("2: i=%d, j=%d, k=%d\n", i, j, k); }

printf("3: i=%d, j=%d, k=%d\n", i, j, k);}

C Program DesignFunctions and Program Structure

Extern Variables

Local (Private) Variables

#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int maxline);void copy(char to[], const char from[]);

/* print the longest input line */main(){ int len; /* current line length */ int max; /* maximum length seen so far */ char line[MAXLINE]; /* current input line */ char longest[MAXLINE]; /* longest line saved here */

max = 0; while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len;

copy(longest, line); } if (max > 0) /* there was a line */

printf("%s", longest); return 0;}

#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int maxline);void copy(char to[], const char from[]);

/* print the longest input line */main(){ int len; /* current line length */ int max; /* maximum length seen so far */ char line[MAXLINE]; /* current input line */ char longest[MAXLINE]; /* longest line saved here */

max = 0; while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len;

copy(longest, line); } if (max > 0) /* there was a line */

printf("%s", longest); return 0;}

/* getline: read a line into s, return length *//* simplified version */int getline(char s[],int lim){ int c, i;

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n';) s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i;}

/* copy: copy 'from' into 'to'; assume to is big enough */

void copy(char to[], const char from[])

{

int i;

i = 0;

while ((to[i] = from[i]) != '\0') ++i;

}

/* getline: read a line into s, return length *//* simplified version */int getline(char s[],int lim){ int c, i;

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n';) s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i;}

/* copy: copy 'from' into 'to'; assume to is big enough */

void copy(char to[], const char from[])

{

int i;

i = 0;

while ((to[i] = from[i]) != '\0') ++i;

}

Local (Private) Variables

#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int maxline);void copy(char to[], const char from[]);

/* print the longest input line */main(){ int len; /* current line length */ int max; /* maximum length seen so far */ char line[MAXLINE]; /* current input line */ char longest[MAXLINE]; /* longest line saved here */

max = 0; while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len;

copy(longest, line); } if (max > 0) /* there was a line */

printf("%s", longest); return 0;}

#include <stdio.h>#define MAXLINE 1000 /* maximum input line length */

int getline(char line[], int maxline);void copy(char to[], const char from[]);

/* print the longest input line */main(){ int len; /* current line length */ int max; /* maximum length seen so far */ char line[MAXLINE]; /* current input line */ char longest[MAXLINE]; /* longest line saved here */

max = 0; while ((len = getline(line, MAXLINE)) > 0) if (len > max) { max = len;

copy(longest, line); } if (max > 0) /* there was a line */

printf("%s", longest); return 0;}

/* getline: read a line into s, return length *//* simplified version */int getline(char s[],int lim){ int c, i;

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n';) s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i;}

/* copy: copy 'from' into 'to'; assume to is big enough */

void copy(char to[], const char from[])

{

int i;

i = 0;

while ((to[i] = from[i]) != '\0') ++i;

}

/* getline: read a line into s, return length *//* simplified version */int getline(char s[],int lim){ int c, i;

for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n';) s[i++] = c; if (c == '\n') s[i++] = c; s[i] = '\0'; return i;}

/* copy: copy 'from' into 'to'; assume to is big enough */

void copy(char to[], const char from[])

{

int i;

i = 0;

while ((to[i] = from[i]) != '\0') ++i;

}

Each local variable comes into existence only when the function is called, and disappears when the function is exited.

Hence, also known as automatic variables.

Each local variable comes into existence only when the function is called, and disappears when the function is exited.

Hence, also known as automatic variables.

Global (Extern) Variables

Global variables that are defined external to all functions can be accessed by any function.

Furthermore, they remain in existence permanently.

範例: Print the Longest Line

#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

defined external to all functions

範例: Print the Longest Line

#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

defined external to all functions

/* print longest input line; specialized version */ main(){ int len; extern int max; extern char longest[];

max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); } if (max > 0) /* there was a line */ printf("%s", longest); return 0;}

/* print longest input line; specialized version */ main(){ int len; extern int max; extern char longest[];

max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); } if (max > 0) /* there was a line */ printf("%s", longest); return 0;}

範例: Print the Longest Line

#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

defined external to all functions

/* getline: specialized version */int getline(void){ int c, i; extern char line[];

for (i = 0; i < MAXLINE - 1 && (c=getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i;}

/* getline: specialized version */int getline(void){ int c, i; extern char line[];

for (i = 0; i < MAXLINE - 1 && (c=getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i;}

範例: Print the Longest Line

#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

defined external to all functions

/* copy: specialized version */void copy(void){ int i; extern char line[], longest[];

i = 0; while ((longest[i] = line[i]) != '\0') ++i;}

/* copy: specialized version */void copy(void){ int i; extern char line[], longest[];

i = 0; while ((longest[i] = line[i]) != '\0') ++i;}

範例: Print the Longest Line

#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

defined external to all functions

/* print longest input line; specialized version */ main(){ int len; extern int max; extern char longest[];

max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); } if (max > 0) /* there was a line */ printf("%s", longest); return 0;}

/* print longest input line; specialized version */ main(){ int len; extern int max; extern char longest[];

max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); } if (max > 0) /* there was a line */ printf("%s", longest); return 0;}

/* getline: specialized version */int getline(void){ int c, i; extern char line[];

for (i = 0; i < MAXLINE - 1 && (c=getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i;}

/* getline: specialized version */int getline(void){ int c, i; extern char line[];

for (i = 0; i < MAXLINE - 1 && (c=getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i;}

/* copy: specialized version */void copy(void){ int i; extern char line[], longest[];

i = 0; while ((longest[i] = line[i]) != '\0') ++i;}

/* copy: specialized version */void copy(void){ int i; extern char line[], longest[];

i = 0; while ((longest[i] = line[i]) != '\0') ++i;}

The declarations for referencing external variables are redundant if they are defined in the header part of the same file .

The declarations for referencing external variables are redundant if they are defined in the header part of the same file .

範例: Print the Longest Line(Multiple Source Files) I

/* main.c */#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* main.c */#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* functions.c *//* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

/* functions.c *//* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

範例: Print the Longest Line(Multiple Source Files) I

/* main.c */#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* main.c */#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* functions.c *//* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

/* functions.c *//* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

/* print longest input line; specialized version */ main(){ int len; extern int max; extern char longest[];

max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); } if (max > 0) /* there was a line */ printf("%s", longest); return 0;}

/* print longest input line; specialized version */ main(){ int len; extern int max; extern char longest[];

max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); } if (max > 0) /* there was a line */ printf("%s", longest); return 0;}

/* getline: specialized version */int getline(void){ int c, i; extern char line[];

for (i = 0; i < MAXLINE - 1 && (c=getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i;}

/* getline: specialized version */int getline(void){ int c, i; extern char line[];

for (i = 0; i < MAXLINE - 1 && (c=getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i;}

/* copy: specialized version */void copy(void){ int i; extern char line[], longest[];

i = 0; while ((longest[i] = line[i]) != '\0') ++i;}

/* copy: specialized version */void copy(void){ int i; extern char line[], longest[];

i = 0; while ((longest[i] = line[i]) != '\0') ++i;}

Must be kept.Must be kept.

Must be kept.Must be kept.

範例: Print the Longest Line(Multiple Source Files) II

/* main.c */#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* main.c */#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* functions.c */#include <stdio.h>#include "externdef.h"/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

/* functions.c */#include <stdio.h>#include "externdef.h"/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

/* externdef.h */#define MAXLINE 1000 /* maximum input line size */

extern int max; /* maximum length seen so far */extern char line[]; /* current input line */extern char longest[]; /* longest line saved here */

/* externdef.h */#define MAXLINE 1000 /* maximum input line size */

extern int max; /* maximum length seen so far */extern char line[]; /* current input line */extern char longest[]; /* longest line saved here */

範例: Print the Longest Line(Multiple Source Files) II

/* main.c */#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* main.c */#include <stdio.h>

#define MAXLINE 1000 /* maximum input line size */

int max; /* maximum length seen so far */char line[MAXLINE]; /* current input line */char longest[MAXLINE]; /* longest line saved here */

int getline(void);void copy(void);

/* print longest input line; specialized version */main(){ . . . . . . . . . . . . }

/* functions.c */#include <stdio.h>#include "externdef.h"/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

/* functions.c */#include <stdio.h>#include "externdef.h"/* getline: specialized version */int getline(void){ . . . . . . . . . . . . }

/* copy: specialized version */void copy(void){ . . . . . . . . . . . . }

/* externdef.h */#define MAXLINE 1000 /* maximum input line size */

extern int max; /* maximum length seen so far */extern char line[]; /* current input line */extern char longest[]; /* longest line saved here */

/* externdef.h */#define MAXLINE 1000 /* maximum input line size */

extern int max; /* maximum length seen so far */extern char line[]; /* current input line */extern char longest[]; /* longest line saved here */

/* getline: specialized version */int getline(void){ int c, i; extern char line[];

for (i = 0; i < MAXLINE - 1 && (c=getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i;}

/* getline: specialized version */int getline(void){ int c, i; extern char line[];

for (i = 0; i < MAXLINE - 1 && (c=getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i;}

/* copy: specialized version */void copy(void){ int i; extern char line[], longest[];

i = 0; while ((longest[i] = line[i]) != '\0') ++i;}

/* copy: specialized version */void copy(void){ int i; extern char line[], longest[];

i = 0; while ((longest[i] = line[i]) != '\0') ++i;}

C Program DesignFunctions and Program Structure

Static Variables

Static Variables

Static Local Variables– continue to exist even after the function

(block) in which they are defined terminates– may be initialized in their declarations

Static External Variables– can be accessed as external variables only in

the file in which they are defined

範例:

#include <stdio.h>

#define ACC_ADD 0#define ACC_TOTAL 1#define ACC_COUNT 2

int accumulator();

main(){ int num; while(1){ printf("Enter a positive integer or -1 to end:"); scanf("%d", &num); if(num<0) break; accumulator(ACC_ADD, num); }

printf("You have entered %d intergers. Their sum is %d.\n", accumulator(ACC_COUNT), accumulator(ACC_TOTAL));}

int accumulator(int function, int val){ static int total=0, count=0;

switch(function){ case ACC_ADD: count++; total += val; case ACC_TOTAL: return total; default: return count; }}

#include <stdio.h>

#define ACC_ADD 0#define ACC_TOTAL 1#define ACC_COUNT 2

int accumulator();

main(){ int num; while(1){ printf("Enter a positive integer or -1 to end:"); scanf("%d", &num); if(num<0) break; accumulator(ACC_ADD, num); }

printf("You have entered %d intergers. Their sum is %d.\n", accumulator(ACC_COUNT), accumulator(ACC_TOTAL));}

int accumulator(int function, int val){ static int total=0, count=0;

switch(function){ case ACC_ADD: count++; total += val; case ACC_TOTAL: return total; default: return count; }}

累加器

範例:

#include <stdio.h>

#define ACC_ADD 0#define ACC_TOTAL 1#define ACC_COUNT 2

int accumulator();

main(){ int num; while(1){ printf("Enter a positive integer or -1 to end:"); scanf("%d", &num); if(num<0) break; accumulator(ACC_ADD, num); }

printf("You have entered %d intergers. Their sum is %d.\n", accumulator(ACC_COUNT), accumulator(ACC_TOTAL));}

int accumulator(int function, int val){ static int total=0, count=0;

switch(function){ case ACC_ADD: count++; total += val; case ACC_TOTAL: return total; default: return count; }}

#include <stdio.h>

#define ACC_ADD 0#define ACC_TOTAL 1#define ACC_COUNT 2

int accumulator();

main(){ int num; while(1){ printf("Enter a positive integer or -1 to end:"); scanf("%d", &num); if(num<0) break; accumulator(ACC_ADD, num); }

printf("You have entered %d intergers. Their sum is %d.\n", accumulator(ACC_COUNT), accumulator(ACC_TOTAL));}

int accumulator(int function, int val){ static int total=0, count=0;

switch(function){ case ACC_ADD: count++; total += val; case ACC_TOTAL: return total; default: return count; }}

累加器

範例: // file1.c

static int nValue; // file scoped variablefloat fValue; // global variable int main(){ double dValue; // local variable}

// file1.c

static int nValue; // file scoped variablefloat fValue; // global variable int main(){ double dValue; // local variable}

// file2.c

static int nValue; // file scoped variablefloat fValue; // global variable int fun(){ double dValue; // local variable}

// file2.c

static int nValue; // file scoped variablefloat fValue; // global variable int fun(){ double dValue; // local variable}

範例: // file1.c

static int nValue; // file scoped variablefloat fValue; // global variable int main(){ double dValue; // local variable}

// file1.c

static int nValue; // file scoped variablefloat fValue; // global variable int main(){ double dValue; // local variable}

// file2.c

static int nValue; // file scoped variablefloat fValue; // global variable int fun(){ double dValue; // local variable}

// file2.c

static int nValue; // file scoped variablefloat fValue; // global variable int fun(){ double dValue; // local variable}

範例: // file1.c

static int nValue; // file scoped variablefloat fValue; // global variable int main(){ double dValue; // local variable}

// file1.c

static int nValue; // file scoped variablefloat fValue; // global variable int main(){ double dValue; // local variable}

// file2.c

static int nValue; // file scoped variablefloat fValue; // global variable int fun(){ double dValue; // local variable}

// file2.c

static int nValue; // file scoped variablefloat fValue; // global variable int fun(){ double dValue; // local variable}

extern float fValue; // global variable

C Program DesignFunctions and Program Structure

Recursion

Factorial

! ( 1) ( 2) ( 3) 2 1n n n n n

! ( 1)!n n n ( 1)! ( 1) ( 2)!n n n

( 2)! ( 2) ( 3)!n n n

2! 2 1! 1! 1

Factorial

範例: Factorial#include <stdio.h>

int factorial(int);

main(){ int n;

while(1){ printf("Enter a positive integer:"); scanf("%d", &n); if(n<=0) break; printf("%d!=%d\n", n, factorial(n)); }}

// recursive versionint factorial(int n) { if(n==1) return 1; return n * factorial(n-1);}

#include <stdio.h>

int factorial(int);

main(){ int n;

while(1){ printf("Enter a positive integer:"); scanf("%d", &n); if(n<=0) break; printf("%d!=%d\n", n, factorial(n)); }}

// recursive versionint factorial(int n) { if(n==1) return 1; return n * factorial(n-1);}

Greatest Common Divisor

681 534

486 148 81

133 4848

215 3333

53 15

30

150

gcd(81, 534) = ?

Greatest Common Divisor

681 534

486 148 81

133 4848

215 3333

53 15

30

150

gcd(81, 534) = ?= 3

= gcd(534 % 81, 81) = gcd(48, 81)

= gcd(81 % 48, 48) = gcd(33, 48)

= gcd(48 % 33, 33) = gcd(15, 33)

= gcd(33 % 15, 15) = gcd(3, 15)

534 % 81 = 48

81 % 48 = 33

48 % 33 = 15

33 % 15 = 3

15 % 3 = 0

範例 :GCD (Euclidean algorithm)

#include <stdio.h>

int gcd(int, int);

main(){ int a, b;

while(1){ printf("Enter two non-zero & postive integers:"); scanf("%d %d", &a, &b); printf("gcd(%d, %d)=%d\n", a, b, gcd(a, b)); }}

int gcd(int a, int b) // non-recursive verison{ int temp;

while((temp = b % a) != 0){ b = a; a = temp; } return a;}

#include <stdio.h>

int gcd(int, int);

main(){ int a, b;

while(1){ printf("Enter two non-zero & postive integers:"); scanf("%d %d", &a, &b); printf("gcd(%d, %d)=%d\n", a, b, gcd(a, b)); }}

int gcd(int a, int b) // non-recursive verison{ int temp;

while((temp = b % a) != 0){ b = a; a = temp; } return a;}

681 534

486 148 81

133 4848

215 3333

53 15

30

150

non-recursive version

範例 :GCD (Euclidean algorithm)

#include <stdio.h>

int gcd(int, int);

main(){ int a, b;

while(1){ printf("Enter two non-zero & postive integers:"); scanf("%d %d", &a, &b); printf("gcd(%d, %d)=%d\n", a, b, gcd(a, b)); }}

int gcd(int a, int b) // non-recursive verison{ int temp;

while((temp = b % a) != 0){ b = a; a = temp; } return a;}

#include <stdio.h>

int gcd(int, int);

main(){ int a, b;

while(1){ printf("Enter two non-zero & postive integers:"); scanf("%d %d", &a, &b); printf("gcd(%d, %d)=%d\n", a, b, gcd(a, b)); }}

int gcd(int a, int b) // non-recursive verison{ int temp;

while((temp = b % a) != 0){ b = a; a = temp; } return a;}

681 534

486 148 81

133 4848

215 3333

53 15

30

150

non-recursive version

範例 :GCD (Euclidean algorithm)

#include <stdio.h>

int gcd(int, int);

main(){ int a, b;

while(1){ printf("Enter two non-zero & postive integers:"); scanf("%d %d", &a, &b); printf("gcd(%d, %d)=%d\n", a, b, gcd(a, b)); }}

int gcd(int a, int b) // recursive verison{ if (b % a == 0) return a; return gcd(b % a, a);}

#include <stdio.h>

int gcd(int, int);

main(){ int a, b;

while(1){ printf("Enter two non-zero & postive integers:"); scanf("%d %d", &a, &b); printf("gcd(%d, %d)=%d\n", a, b, gcd(a, b)); }}

int gcd(int a, int b) // recursive verison{ if (b % a == 0) return a; return gcd(b % a, a);}

681 534

486 148 81

133 4848

215 3333

53 15

30

150

gcd(81, 534)

gcd(48, 81)

gcd(33, 48)

gcd(15, 33)

gcd(3, 15)

recursive version

範例 :GCD (Euclidean algorithm)

#include <stdio.h>

int gcd(int, int);

main(){ int a, b;

while(1){ printf("Enter two non-zero & postive integers:"); scanf("%d %d", &a, &b); printf("gcd(%d, %d)=%d\n", a, b, gcd(a, b)); }}

int gcd(int a, int b) // recursive verison{ if (b % a == 0) return a; return gcd(b % a, a);}

#include <stdio.h>

int gcd(int, int);

main(){ int a, b;

while(1){ printf("Enter two non-zero & postive integers:"); scanf("%d %d", &a, &b); printf("gcd(%d, %d)=%d\n", a, b, gcd(a, b)); }}

int gcd(int a, int b) // recursive verison{ if (b % a == 0) return a; return gcd(b % a, a);}

681 534

486 148 81

133 4848

215 3333

53 15

30

150

gcd(81, 534)

gcd(48, 81)

gcd(33, 48)

gcd(15, 33)

gcd(3, 15)

recursive version

A Combinatorial Problem

A person has to climb 22 steps; at each point he has two choices; he can either choose to climb one step ahead or two steps ahead; you have to tell the total possible ways of climbing the steps.

A Combinatorial Problem

n steps

f (n) = ?

A Combinatorial Problem

n steps

f (n) = ?n – 1 steps

f (n – 1)

A Combinatorial Problem

n steps

n – 2 steps

f (n – 2)

f (n) = ?

A Combinatorial Problem

n steps

f (n) = ?= f (n 1) + f (n 2)

A Combinatorial Problem

n steps

f (n) = ?= f (n 1) + f (n 2)

A person has to climb 22 steps; at each point he has two choices; he can either choose to climb one step ahead or two steps ahead; you have to tell the total possible ways of climbing the steps.

f (22) = f (21) + f (20)

f (21) = f (20) + f (19)

f (20) = f (19) + f (18)

f (1) = ?

f (2) = ?

f (3) = f (2) + f (1) = 3

f (4) = f (3) + f (2) = 5

.

.

.

1

2

f (n) = f (n 1) + f (n 2)f (2) = 1 f (1) = 1

Fibonacci Series

1 1 2 3 5 8 13 21 34 55 89 144 …

f (n) = f (n 1) + f (n 2)f (2) = 1 f (1) = 1

範例: Fibonacci Series

f (n) = f (n 1) + f (n 2)f (2) = 1 f (1) = 1

#include <stdio.h>

int Fib(int);

main(){ int n;

while(1){ printf("Enter a positive integer:"); scanf("%d", &n); if(n<=0) break; printf("Fib(%d)=%d\n", n, Fib(n)); }}

// recursive versionint Fib(int n) { if(n==1 || n==2) return 1; return Fib(n-1) + Fib(n-2);}

#include <stdio.h>

int Fib(int);

main(){ int n;

while(1){ printf("Enter a positive integer:"); scanf("%d", &n); if(n<=0) break; printf("Fib(%d)=%d\n", n, Fib(n)); }}

// recursive versionint Fib(int n) { if(n==1 || n==2) return 1; return Fib(n-1) + Fib(n-2);}

練習 :[5.36]

1. Tower of Hanoi

練習 :2. In combinatorial mathematics, n-choose-k is defined by

which has the following recursive property:

Write a C function int n_choose_k(int n, int k)which computes n-choose-k recursively. Verify your code.

!,

( )! !

n n

k n k k

1 1

1

n n n

k k k

and 1, 10

n n

n

練習 :3. Writing a recursive C function

int recursiveMin(int vals[], int size)

which returns the minimum value in array vals of size size. Verify your code.

練習 :4. Writing a recursive C function

void reverse(char str[])

which reverses the order of str. For example, if str="hello", after calling reverse(str), str will become "olleh", verify your code. (Hint: You may need to define another help function to facilitate your job.)

Recommended