项目8的实现,main函数太臃肿,不便于阅读和维护。ide
用函数来优化。函数
#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; }
已经有main函数,为何还要自定义函数?
1)“避免重复制造轮子”,提升开发效率性能
2)便于维护优化
函数的设计方法:
1)先肯定函数的功能
2)肯定函数的参数
是否须要参数,参数的个数,参数的类型
3)肯定函数的返回值
是否须要返回值,返回值的类型设计
函数的声明3d
函数的使用指针
调用函数时,形参被赋值为对应的实参,
实参自己不会受到函数的影响!code
要避免栈空间溢出。
当调用一个函数时,就会在栈空间,为这个函数,分配一块内存区域,
这块内存区域,专门给这个函数使用。
这块内存区域,就叫作“栈帧”。blog
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; }
定义:在函数的内部,直接或者间接的调用本身。
要点:
再定义递归函数时,必定要肯定一个“结束条件”!!!
使用场合:
处理一些特别复杂的问题,难以直接解决。
可是,能够有办法把这个问题变得更简单(转换成一个更简单的问题)。
盗梦空间
例如:
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;
}
递归函数的缺点:
性能很低!!!
独立完成项目9
定义一个函数,实现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; }
打印指定类型的金字塔,用自定义函数实现。
效果以下:
代码:
#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; }
#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; }
#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; }