欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

2020.9.18 用函数是实现模块化程序

程序员文章站 2022-06-12 16:48:05
...

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;
}
相关标签: c语言