打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
「小白到大牛之路9」交换机后台管理系统之函数优化

项目需求

项目8的实现,main函数太臃肿,不便于阅读和维护。

项目实现

用函数来优化。

#include <stdio.h>#include <string.h>#include <stdlib.h>FILE *file; void init(void) { //打开文件 file = fopen('users.txt', 'r'); if (!file) { //等效于 file == NULL printf('文件打开失败'); //return 1; exit(1); }}void login(void) { char name[32]; char password[16]; char line[128]; char name_tmp[32]; char password_tmp[16]; char *ret; //输入用户名和密码 while (1) { system('cls'); // 输入用户名和密码 printf('请输入用户名:'); scanf('%s', name); printf('请输入密码:'); scanf('%s', password); //从文件中读取账号,并进行判断! while (1) { //读一行 ret = fgets(line, sizeof(line), file); //line: 'admin 123456\n' if (!ret) { break; } sscanf(line, '%s %s', name_tmp, password_tmp); if (!strcmp(name, name_tmp) && !strcmp(password, password_tmp)) { break; } } if (ret) { //用户名和密码匹配成功 break; } else { printf('用户名或密码错误!\n'); system('pause'); system('cls'); fseek(file, 0, SEEK_SET); //把文件内部的位置指针设置到文件头 } }}void create_user(void) { system('cls'); printf('\n\n---创建账号---\n\n'); printf('待实现...\n\n'); printf('\n\n按任意键返回主菜单'); fflush(stdin); getchar();}void ip_admin(void) { system('cls'); printf('\n\n---IP管理---\n\n'); printf('待实现...\n\n'); printf('\n\n按任意键返回主菜单'); fflush(stdin); getchar();}void logout(void) { system('cls'); fclose(file); exit(0);}void input_error(void) { system('cls'); printf('\n\n输入错误!\n\n'); printf('\n\n按任意键后,请重新输入\n\n'); fflush(stdin); getchar();}void show_memu(void) { system('cls'); // 打印功能菜单 printf('---交换机后台管理---\n'); printf('1. 创建账号\n'); printf('2. IP管理\n'); printf('3. 退出\n'); printf('请选择: ');}int main(void) { char n; //用户选择的菜单编号 init(); //初始化 login(); //登录 while (1) { show_memu(); fflush(stdin); scanf('%c', &n); switch (n) { case '1': create_user(); break; case '2': ip_admin(); break; case '3': logout(); break; default: input_error(); break; } } return 0;}

项目精讲

1. 为什么要使用函数

已经有main函数,为什么还要自定义函数?

1) '避免重复制造轮子',提高开发效率

2)便于维护

2. 函数的声明、定义和使用

函数的设计方法:

1) 先确定函数的功能

2) 确定函数的参数

是否需要参数,参数的个数,参数的类型

3) 确定函数的返回值

是否需要返回值,返回值的类型

函数的声明

函数的使用

3. 函数的值传递

调用函数时,形参被赋值为对应的实参,

实参本身不会受到函数的影响!

4. 函数的栈空间

要避免栈空间溢出。

当调用一个函数时,就会在栈空间,为这个函数,分配一块内存区域,

这块内存区域,专门给这个函数使用。

这块内存区域,就叫做'栈帧'。

demo1

#include <stdio.h>#include <string.h>void test(void) {	//运行时将因为栈帧空间溢出,而崩溃	char buff[1024*1024*2];	memset(buff, 0, sizeof(buff));}int main(void) {	test();	return 0;}

demo2

#include <stdio.h>#include <string.h>void test(int n) { char buff[1024*256]; memset(buff, 0, sizeof(buff)); if (n==0) { return; } printf('n=%d\n', n); test(n-1);}int main(void) { //test(5); //因为每个栈帧有256K以上, 10个栈帧超出范围 test(10); return 0;}

5. 递归函数

定义:在函数的内部,直接或者间接的调用自己。

要点:

再定义递归函数时,一定要确定一个'结束条件'!!!

使用场合:

处理一些特别复杂的问题,难以直接解决。

但是,可以有办法把这个问题变得更简单(转换成一个更简单的问题)。

盗梦空间

例如:

1) 迷宫问题

2) 汉诺塔问题

斐波那契数列

1, 1, 2, 3, 5, 8, 13, 21, ....

计算第n个数是多少?

f(n)

当n >2时,f(n) = f(n-1) + f(n-2)

当n=1或n=2时, f(n)就是1

int fib(int n) {

int s;

if (n == 1|| n == 2) {

return 1;

}

s = fib(n-1) + fib(n-2);

return s;

}

递归函数的缺点:

性能很低!!!

项目练习

1. 练习1

独立完成项目9

2. 练习2

定义一个函数,实现1+2+3+...+n

#include <stdio.h>int sum(int n) {	int i;	int s = 0;		for (i=1; i<=n; i++) {		s += i;	}		return s;}int main(void) {	int value;		printf('请输入一个整数: ');	scanf('%d', &value);	if (value < 0) {		printf('需要大于0\n');		return 1;	}		printf('%d\n', sum(value));		return 0;}

3. 打印金字塔

打印指定类型的金字塔,用自定义函数实现。

效果如下:

代码:

#include <stdio.h>void show(char c, int n) { int i; int j; for (i=1; i<=n; i++) { for (j=0; j<n-i; j++) { printf(' '); } for (j=0; j<2*i-1; j++) { printf('%c', c); } printf('\n'); }}int main(void) { char c; int n; printf('请输入金字塔的组成字符: '); scanf('%c', &c); if (c == '\n' || c == ' ' || c == '\t') { printf('请输入一个非空白字符\n'); return 1; } printf('请输入金字塔的层数: '); scanf('%d', &n); if (n < 1) { printf('层数需要大于0\n'); return 1; } show(c, n); return 0;}

4. 用递归函数实现练习2

#include <stdio.h>int sum(int n) {	int s;		if (n == 1) {		return 1;	}		s = n + sum(n-1);		return s;}int main(void) {	int value;		printf('请输入一个整数: ');	scanf('%d', &value);		if (value < 0) {		printf('需要大于0\n');		return 1;	}		printf('%d\n', sum(value));		return 0;}

5. 用递归函数实现汉诺塔

#include <stdio.h>void hanoi(int n, char pillar_start[], char pillar_mid[], char pillar_end[]) { if (n == 1) { printf('从%s移动到%s\n', pillar_start, pillar_end); return; } hanoi(n-1, pillar_start, pillar_end, pillar_mid); printf('从%s移动到%s\n', pillar_start, pillar_end); hanoi(n-1, pillar_mid, pillar_start, pillar_end); }int main(void) { char name1[] = 'A柱'; char name2[] = 'B柱'; char name3[] = 'C柱'; int n = 3; //盘子数 hanoi(3, name1, name2, name3); return 0;}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C程序设计的常用算法
读入优化&输出优化
全排列
C语言基础笔试题
【蓝桥杯系列】第一节 C的基本用法
C语言难点分析整理
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服