2020.9.18 用函数是实现模块化程序
2020.9.18 用函数是实现模块化程序
一、认识函数
1.函数的组成
函数返回值类型 函数名(参数表)
{
函数体;
return 数据;
}
函数返回值类型 —>return 后面的数据的类型
void :空 —>没有
1.1 任何函数遇到return 该函数结束
1.2 不写返回值,默认为int
1.3 void返回值能不能return? 可以return
1.4 函数返回值是函数唯一的遗留物 他是一个值
函数名: 随便写什么东西 —>标识符
参数表: 定义的变量
函数体: 写的代码
2.常见的函数形态
2.1 功能描述
没有返回值,无参数,单纯是装一段代码
2.2 数据处理
无返回值有参
2.3 充当状态分析
0,1
3.函数参数
都是参数赋值的方式
形参:形式参数 定义函数的时候叫做形参
实参:实际参数 调用的时候用参数
理解: 形参是实参拷贝本
4.调用函数
函数名(实际参数);
通常参数需要和形参保持类型和数目的一致性
#include <stdio.h>
//没有参数没有返回值
//NULL void*
void makeMenu(void) //等效 void makeMenu();
{
printf("---------【自动关机小程序】----------\n");
printf("\t\t0.退出系统\n");
printf("\t\t1.立刻关机\n");
printf("\t\t2.定时关机\n");
printf("------------------------------------\n");
return; //不返回任何东西,对于void
}
//条件判断:状态
int gameOver()
{
return 1;
if (1)
return 0;
else
return 1;
}
//数据处理
int sum(int a, int b) //形参 int a=实参1 int b=实参2
{
a = 1001;
return a + b;
}
//默认为int类型
print()
{
printf("我没有返回值");
}
//缺少返回值
//不是所有的控件都具有返回值
// “returnNum”: 不是所有的控件路径都返回值
int returnNum()
{
for (int i = 0; i < 3; i++)
if (i == 2)
return i;
//
return -1; //通过返回一个垃圾值充当没有满足条件的返回值
}
#include <stdio.h>
int main()
{
//函数调用
sum(1, 2); //1,2 实参
//int sum(1,2); 错误
int aa = 1;
int bb = 2;
sum(aa, bb);
print();
//函数返回值是函数调用后的唯遗留物
//函数调用后这个表达式的值
//赋值
int result=sum(2, 3);
//做算数运算符
result = sum(2, 3) * 2;
printf("%d", sum(2, 3));
//sum(2, 3) = 12;
return 0; //int 数据
}
二、函数的定义与声明
函数定义和声明问题:
1.未定义问题
1.1 编译顺序问题,程序用到的东西一定是要已经存在的
1.2 声明函数可以不写形参名,实现函数必须带参数
2.无法的解析的xxx符号
无法解析的外部符号 _MIN,函数 _main 中引用了该符号
2.1 通常情况调用时候函数名字写错
2.2 函数没有实现
#include <stdio.h>
void print();
int max(int, int);
//int MIN(int, int);
int main()
{
//Min(1, 2);
return 0;
}
void print()
{
//warning C4013: “max”未定义;假设外部返回 int
printf("%d", max(1, 2));
}
int max(int a, int b)
{
return a > b ? a : b;
}
三、函数调用
嵌套调用
1.1 通过函数返回值充当参数的方式去嵌套调用
1.2 通过参数的递推实现递归调用
如何写函数递归:
1.1 退出性条件
1.2 数学递归公式
F(1)=1 退出条件
F(2)=1; 退出条件
f(3)=f(2)+f(1);
f(n)=f(n-1)+f(n-2); n>2 递归公式
#include <stdio.h>
int Max(int a, int b)
{
return a > b ? a : b;
}
int f(int n)
{
if (n == 1 || n == 2)
return 1;
return f(n - 1) + f(n - 2);
}
//求阶乘 1!=1
// 2!=2*1
// 3!=3*2*1
// f(n)=n*f(n-1); n>1
int 阶乘(int n)
{
if (n == 1)
return 1;
return 阶乘(n - 1) * n; //5*4! 5*4*3!
}
int main()
{
int a = 1;
int b = 2;
int c = 3;
printf("%d", Max(Max(Max(a, b), c),4));
int ab = Max(a, b);
int abc = Max(ab, c);
Max(abc, 4);
printf("%d\n", f(3));
printf("%d\n", 阶乘(5));
return 0;
}
四、函数传参
1.传参就是一个赋值过程
所以形参只是实参的拷贝本
2.特殊的传参
2.1 处理数组数据
通常都会传入一个数组长度进去
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void 自己写的函数(int a)
{
a = 1001;
printf("函数中:%d\n", a);
}
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
//一维数组
void initArray(int array[], int arrayNum)
{
for (int i = 0; i < arrayNum; i++)
{
array[i] = i;
}
}
void printArray(int array[], int arrayNum)
{
for (int i = 0; i < arrayNum; i++)
{
printf("%d\t", array[i]);
}
printf("\n");
}
//传入二维数组
void initArray2D(int array[][3], int row, int cols)
{
printf("传入二维数组\n");
}
int main()
{
int a = 1;
自己写的函数(a);
printf("%d\n", a);
int array[3];
//传参是数组名
initArray(array, 3);
printArray(array, 3);
char str[20];
gets_s(str, 20);
puts(str);
char userKey = getchar();
int array2D[2][3];
initArray2D(array2D, 2, 3);
//“函数”:“int (*)[3]”与“int [3]”的间接级别不同
//形参和实参 1 的类型不同
//initArray2D(array, 2, 3);
return 0;
}
五、处理数据过程
/*
封装一维数组的增删改查
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//保证元素的有序性
int insertArray(int array[], int curSize, int posData)
{
//1 2 4
//3
// 1 2 3 4
//当数组的当前元素是0
if (curSize == 0)
{
array[0] = posData;
return 1;
}
//1 2 4
//8
int pos = -1;
for (int i = 0; i < curSize; i++)
{
//找到第一个大于我们插入数据的位置
if (array[i] > posData)
{
pos = i;
break;
}
}
if (pos == -1)
{
array[curSize] = posData;
}
else
{
//整个数据往右变移动,腾出来位置
for (int i = curSize; i > pos; i--)
{
array[i] = array[i - 1];
}
array[pos] = posData;
}
return curSize+1;
}
void printArray(int array[], int curSize)
{
for (int i = 0; i < curSize; i++)
printf("%d\t", array[i]);
printf("\n");
}
int deleteArray(int array[], int curSize, int posData)
{
int pos = -1;
for (int i = 0; i < curSize; i++)
{
if (array[i] == posData)
{
pos = i;
}
}
if (pos == -1)
{
return curSize;
}
else
{
for (int i = pos; i < curSize; i++)
{
array[i] = array[i + 1];
}
curSize--;
return curSize;
}
}
int main()
{
srand((unsigned int)time(NULL));
int array[1024]; //一段内存
int curSize = 0; //当前元素个数
int posData = 1;
for (int i = 0; i < 10; i++)
{
curSize = insertArray(array, curSize, rand()%10);
}
printArray(array, curSize);
curSize = deleteArray(array, curSize, 8);
printArray(array, curSize);
return 0;
}
六、变量 以及作用域
#include <stdio.h>
#include <stdlib.h>
int g_num = 0;
void print()
{
g_num = 1001;
}
void print2()
{
g_num++;
}
//静态变量
void printStatic()
{
static int s_num = 1001; //静态变量的初始化只做一次
s_num++;
printf("%d\n", s_num);
}
int main()
{
int i = 0;
for (int i = 0; i < 10; i++)
{
if (i == 5)
break;
}
printf("%d\n", i);
print();
print2();
printf("%d\n", g_num);
printStatic();
printStatic();
return 0;
}
七、模块化程序 实例
/*
模块化:按照功能去划分程序员
遵循原则:单一性原则 一个函数只做一个事情,或者只实现一个功能
*/
让所有的函数都能访问访问这个数组:全局变量 //也可以通过传参的方式。
尽量减少全局变量的使用
1.画图 2.结束判断 3.定位 i,j坐标 4.按键操作
#include <stdio.h>
#include <conio.h> //_getch
#include <stdlib.h> //system
//设计地图 --->全局变量
int cas = 0;
int map[3][8][8] =
{
1,1,1,1,1,1,1,1,
1,3,4,0,0,4,3,1,
1,0,1,0,1,1,0,1,
1,0,1,0,1,1,0,1,
1,0,0,5,0,0,0,1,
1,0,1,0,1,1,0,1,
1,3,4,0,0,4,3,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,3,4,0,0,4,3,1,
1,0,1,0,1,1,0,1,
1,0,1,0,1,1,0,1,
1,3,4,5,0,0,0,1,
1,0,1,0,1,1,0,1,
1,3,4,0,0,4,3,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,3,4,0,0,4,3,1,
1,0,1,0,1,1,0,1,
1,0,1,0,1,1,0,1,
1,3,4,5,0,4,3,1,
1,0,1,0,1,1,0,1,
1,3,4,0,0,4,3,1,
1,1,1,1,1,1,1,1
};
void drawMap()
{
//画地图
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
switch (map[cas][i][j])
{
case 0:
printf(" "); //汉字符号占用两个字节
break;
case 1:
printf("■");
break;
case 3:
printf("☆");
break;
case 4:
printf("★");
break;
case 5:
case 8:
printf("♀");
break;
case 7:
printf("●");
break;
}
}
printf("\n");
}
}
int searchPos_i()
{
int i, j;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
if (map[cas][i][j] == 5 || map[cas][i][j] == 8)
{
return i;
}
}
}
return -1;
} //找人物的i坐标
int searchPos_j()
{
int i, j;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
if (map[cas][i][j] == 5 || map[cas][i][j] == 8)
{
return j;
}
}
}
return -1;
}
void keyDown()
{
int i = searchPos_i();
int j = searchPos_j();
//按键控制的框架
char userKey = _getch();
switch (userKey)
{
case 'W':
case 'w':
case 72:
if (map[cas][i - 1][j] == 0 || map[cas][i - 1][j] == 3)
{
map[cas][i - 1][j] += 5; //新的地方人来
map[cas][i][j] -= 5; //原来的地方人走了
}
if (map[cas][i - 1][j] == 4 || map[cas][i - 1][j] == 7)
{
if (map[cas][i - 2][j] == 0 || map[cas][i - 2][j] == 3)
{
map[cas][i][j] -= 5;
map[cas][i - 1][j] += 1;
map[cas][i - 2][j] += 4;
}
}
break;
case 's':
case 'S':
case 80:
if (map[cas][i + 1][j] == 0 || map[cas][i + 1][j] == 3)
{
map[cas][i + 1][j] += 5; //新的地方人来
map[cas][i][j] -= 5; //原来的地方人走了
}
if (map[cas][i + 1][j] == 4 || map[cas][i + 1][j] == 7)
{
if (map[cas][i + 2][j] == 0 || map[cas][i + 2][j] == 3)
{
map[cas][i][j] -= 5;
map[cas][i + 1][j] += 1;
map[cas][i + 2][j] += 4;
}
}
break;
case 'A':
case 'a':
case 75:
if (map[cas][i][j - 1] == 0 || map[cas][i][j - 1] == 3)
{
map[cas][i][j - 1] += 5; //新的地方人来
map[cas][i][j] -= 5; //原来的地方人走了
}
if (map[cas][i][j - 1] == 4 || map[cas][i][j - 1] == 7)
{
if (map[cas][i][j - 2] == 0 || map[cas][i][j - 2] == 3)
{
map[cas][i][j] -= 5;
map[cas][i][j - 1] += 1;
map[cas][i][j - 2] += 4;
}
}
break;
case 'D':
case 'd':
case 77:
if (map[cas][i][j + 1] == 0 || map[cas][i][j + 1] == 3)
{
map[cas][i][j + 1] += 5; //新的地方人来
map[cas][i][j] -= 5; //原来的地方人走了
}
if (map[cas][i][j + 1] == 4 || map[cas][i][j + 1] == 7)
{
if (map[cas][i][j + 2] == 0 || map[cas][i][j + 2] == 3)
{
map[cas][i][j] -= 5;
map[cas][i][j + 1] += 1;
map[cas][i][j + 2] += 4;
}
}
break;
}
}
int gameOver()
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if (map[cas][i][j] == 4)
return 0;
}
}
return 1;
}
int main()
{
while (1)
{
printf("第 %d 关\n", cas+1);
drawMap();
if (gameOver())
{
cas++;
if (cas == 3)
{
printf("你成功了\n");
break;
}
else
{
printf("按任意键进入下一关!\n");
}
}
keyDown();
system("cls");
}
return 0;
}
上一篇: AE拓扑规则创建