【小白到大牛之路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;
}

原文地址:https://blog.51cto.com/14632565/2461281

时间: 2024-10-12 03:01:48

【小白到大牛之路9】交换机后台管理系统之函数优化的相关文章

【小白到大牛之路】交换机后台管理之用户输入

项目需求 用户登录时,需要输入用户名和密码. 项目实现 #include <stdio.h> int main(void) {// 定义变量,用来表示用户名和密码char name;int password; // 输入用户名和密码 printf("请输入用户名:"); scanf("%c", &name); printf("请输入密码:"); scanf("%d", &password); /*

【小白到大牛之路】交换机后台管理之登录菜单

交换机后台管理之登录菜单 项目需求 用户打开交换机后台管理程序时,需要进行"登录"操作,以确认用户身份的合法性.所以,我们需要先实现一个登录菜单,以提示用户执行相关操作. 项目实现 启动命令窗口:在运行窗口输入notepad++,再单击"确定". 设置notepad++的语言为C语言: 设置notepad++的编码为ANSI格式编码(便于再CMD中显示中文) main.c #include <stdio.h> int main(void) {// 打印登

TB级(小白到大牛之路)技术视频资源福利大放送

因此民工哥连夜整理了相关的资源放出,相关详情请点击下面的链接查看TB级(小白到大牛之路)技术视频资源福利大放送 更多内容请关注民工哥公众号 原文地址:http://blog.51cto.com/mingongge/2058991

【小白到大牛之路11】交换机后台管理之端口管理的优化

项目需求 项目10中的使用port1,port2,port3,port4,prot5,以及set_port1, set_port2, set_port3, set_port4, set_port5来管理5个端口.代码臃肿.重复,不便于维护. 解决方案:使用结构体数组. 项目实现 修改部分: //定义了5个端口变量 //struct port port1; //struct port port2; //struct port port3; //struct port port4; //struct

【小白到大牛之路12】交换机后台管理之端口管理的再次优化

项目12交换机后台管理之端口管理的再次优化项目精讲 1.为什么要使用指针 函数的值传递,无法通过调用函数,来修改函数的实参. 2.指针定义 指针是什么 指针本质是一个地址值: #include <stdio.h> int main(void){ int age; //定义了一个指针 //指针是一个变量 //这个变量的名称是 p //这个指针,可以用来指向一个整数! //就是说:p的值是一个整数的地址!!! int * p; //指针p指向了age //p的值,就是变量age的地址 p = &a

【小白到大牛之路7】换机后台管理之多用户账号登录

项目需求 实现多个账号 项目实现 #include <stdio.h> #include <string.h> int main(void) { // 定义变量,用来表示用户名和密码 char name[32]; char password[16]; FILE *file; //定义了一个档指针变量,变量名是file char line[128]; char name_tmp[32]; char password_tmp[16]; char *ret; //打开档 file = f

厚着脸皮求领导写了一篇java小白进阶大牛之路!!!

缘起&应朋友之邀 2019年已经过去两个月了,应朋友之邀,写写自己的个人经历,与其说经历还不如是自我的总结与反思.2012年2月份只身一人拖着行李箱来到北京库巴科技有限公司实习,那时候库巴处在高速发展的阶段,我记得那一年库巴招了300多个应届毕业生,光技术就招了50多人,有运维.测试.开发.产品经理.那时候公司有宿舍,4个人一间,上下铺,条件虽然艰苦了一些,但认识了很多好朋友,至今还在保持着联系.下班之余大家经常一起吃饭喝酒,也就是那个时间胖了很多,回学校答辩的时候老师说:“你怎么胖成这样了,都

influxdb 小白到大牛之路

https://github.com/influxdata/influxdb

小白到大牛之路-开发环境搭建

项目1 搭建开发环境 Linux平台开发环境的搭建 1.安装Linux操作系统 建议使用虚拟机vmware方式安装Linux操作系统. Linux操作系统,可选择:1)CentOS(建议:Centos 7.0以上)补充:国内大部分企业的服务器是使用CentOS或(RedHat)CentOS是Redhat的社区版,用法相同.2)Ubuntu系统(不建议) 2.确保Linux操作系统能够上网 建议把虚拟机的网卡设置为桥接模式. 检查:ping www.baidu.com或直接在浏览器中打开百度网站(