一,函数
函数就像我们儿时搭积木的一个个造型各异的木块一样,我们只需要关心该如何使用这些小木块搭建成摩天大楼,而并不需要关心小木块内部究竟有什么结构。函数的设计思想即是将程序内部复杂的逻辑结构封装起来,使用者只需要弄清楚每一个函数的作用,而不需要知道这个函数究竟是如何实现的。我在未学习函数时,写过一个简陋的飞机大战游戏(无GUI界面,只打击移动靶):
如果把全部的功能都放在一个main()函数之中实现,那是比较痛苦的事情,但有了函数,我们可以对每一个功能进行封装实现,这样后期代码的维护以及调试都会比较容易。Source file #include <stdio.h> #include <stdlib.h> #include <conio.h> int main(void) { int i, j; int x = 5; int y = 10; char input; int isFire = 0; int ny = 5; // 一个靶子,放在第一行,ny列上 int isKilled = 0; while (1) { system("cls"); // 清屏函数 // if (!isKilled) // 输出靶子 { for (j = 0; j<ny; j++) printf(" "); printf("+\n"); } if (isFire == 0) // 输出飞机上面的空行 { for (i = 0; i<x; i++) printf("\n"); } else // 输出飞机上面的激光竖线 { for (i = 0; i<x; i++) { for (j = 0; j<y; j++) printf(" "); printf(" |\n"); } if (y + 2 == ny) isKilled = 1; // 击中靶子 isFire = 0; } // 下面输出一个复杂的飞机图案 for (j = 0; j<y; j++) printf(" "); printf(" *\n"); for (j = 0; j<y; j++) printf(" "); printf("*****\n"); for (j = 0; j<y; j++) printf(" "); printf(" * * \n"); if (kbhit()) // 判断是否有输入 { input = getch(); // 根据用户的不同输入来移动,不必输入回车 if (input == 'a') y--; // 位置左移 if (input == 'd') y++; // 位置右移 if (input == 'w') x--; // 位置上移 if (input == 's') x++; // 位置下移 if (input == ' ') isFire = 1; } } return 0; }
在C中,使用函数要注意:
- 首先要使用函数原型(function prototype),告诉编译器函数的类型,包括是否接收变量以及是否返回值。
- 函数调用(function call),表示在某处使用该函数。
- 函数定义(function definition),明确指明函数要做什么。
- 全局变量与局部变量,局部变量(如变量count)只属于某一个函数私有,程序员可以在程序的其他地方,包括main()函数中使用count,这样并不会引起名称的冲突。
- 形式参数与实际参数:实际参数是出现在函数调用圆括号中的表达式,而形式参数则是函数定义的函数头中声明的变量。
原因是:我们首先假设一个函数,需要读取两个int类型的数值,而函数调用只使用了imax(3),在C中,主调函数把它的参数储存在栈(stack)中,被调函数从栈中读取这些参数,被调函数根据函数原型中函数声明的形式参数来读取值,因此,函数调用imax(3),将一个整数放在栈中,而当imax()开始执行时,它要从栈中读取两个整数,但是栈中实际上只放了一个待读取的整数,这样就会引起错误,而如果不首先声明函数原型,并完整的声明函数参数的话,编译器是不会报错的。有了函数原型中的这些信息,编译器可以检查函数调用是否与函数原型相匹配。
No comments:
Post a Comment