溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

【小白到大牛之路9】交換機(jī)后臺(tái)管理系統(tǒng)之函數(shù)優(yōu)化

發(fā)布時(shí)間:2020-07-26 20:00:54 來(lái)源:網(wǎng)絡(luò) 閱讀:295 作者:wx5de7b5143d243 欄目:編程語(yǔ)言

項(xiàng)目需求

項(xiàng)目8的實(shí)現(xiàn),main函數(shù)太臃腫,不便于閱讀和維護(hù)。

項(xiàng)目實(shí)現(xiàn)

用函數(shù)來(lái)優(yōu)化。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

FILE *file; 

void init(void) {
    //打開(kāi)文件
    file = fopen("users.txt", "r");   
    if (!file) {   //等效于 file == NULL  
        printf("文件打開(kāi)失敗");
        //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("請(qǐng)輸入用戶名:");
        scanf("%s", name);
        printf("請(qǐng)輸入密碼:");
        scanf("%s", password);

        //從文件中讀取賬號(hào),并進(jìn)行判斷!
        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("用戶名或密碼錯(cuò)誤!\n");  
            system("pause");
            system("cls");

            fseek(file, 0, SEEK_SET); //把文件內(nèi)部的位置指針設(shè)置到文件頭
        }
    }
}

void create_user(void) {
    system("cls");
    printf("\n\n---創(chuàng)建賬號(hào)---\n\n");
    printf("待實(shí)現(xiàn)...\n\n");
    printf("\n\n按任意鍵返回主菜單");
    fflush(stdin);
    getchar();
}

void ip_admin(void) {
    system("cls");
    printf("\n\n---IP管理---\n\n");
    printf("待實(shí)現(xiàn)...\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輸入錯(cuò)誤!\n\n");
    printf("\n\n按任意鍵后,請(qǐng)重新輸入\n\n");
    fflush(stdin);
    getchar();
}

void show_memu(void) {
    system("cls");
    // 打印功能菜單
    printf("---交換機(jī)后臺(tái)管理---\n");
    printf("1. 創(chuàng)建賬號(hào)\n");
    printf("2. IP管理\n");
    printf("3. 退出\n");
    printf("請(qǐng)選擇: ");
}

int main(void) {
    char n; //用戶選擇的菜單編號(hào)

    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;
}

項(xiàng)目精講

1.為什么要使用函數(shù)

已經(jīng)有main函數(shù),為什么還要自定義函數(shù)?
1)“避免重復(fù)制造輪子”,提高開(kāi)發(fā)效率

2)便于維護(hù)

2.函數(shù)的聲明、定義和使用

函數(shù)的設(shè)計(jì)方法:
1)先確定函數(shù)的功能
2)確定函數(shù)的參數(shù)
是否需要參數(shù),參數(shù)的個(gè)數(shù),參數(shù)的類型
3)確定函數(shù)的返回值
是否需要返回值,返回值的類型

函數(shù)的聲明

函數(shù)的使用

3.函數(shù)的值傳遞

調(diào)用函數(shù)時(shí),形參被賦值為對(duì)應(yīng)的實(shí)參,
實(shí)參本身不會(huì)受到函數(shù)的影響!
【小白到大牛之路9】交換機(jī)后臺(tái)管理系統(tǒng)之函數(shù)優(yōu)化

4.函數(shù)的??臻g

要避免??臻g溢出。
當(dāng)調(diào)用一個(gè)函數(shù)時(shí),就會(huì)在棧空間,為這個(gè)函數(shù),分配一塊內(nèi)存區(qū)域,
這塊內(nèi)存區(qū)域,專門給這個(gè)函數(shù)使用。
這塊內(nèi)存區(qū)域,就叫做“棧幀”。

【小白到大牛之路9】交換機(jī)后臺(tái)管理系統(tǒng)之函數(shù)優(yōu)化
【小白到大牛之路9】交換機(jī)后臺(tái)管理系統(tǒng)之函數(shù)優(yōu)化

demo1

#include <stdio.h>
#include <string.h>

void test(void) {
    //運(yùn)行時(shí)將因?yàn)闂臻g溢出,而崩潰
    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);
    //因?yàn)槊總€(gè)棧幀有256K以上, 10個(gè)棧幀超出范圍
    test(10);  
    return 0;
}

5.遞歸函數(shù)

定義:在函數(shù)的內(nèi)部,直接或者間接的調(diào)用自己。

要點(diǎn):
再定義遞歸函數(shù)時(shí),一定要確定一個(gè)“結(jié)束條件”?。?!

使用場(chǎng)合:
處理一些特別復(fù)雜的問(wèn)題,難以直接解決。
但是,可以有辦法把這個(gè)問(wèn)題變得更簡(jiǎn)單(轉(zhuǎn)換成一個(gè)更簡(jiǎn)單的問(wèn)題)。

盜夢(mèng)空間
【小白到大牛之路9】交換機(jī)后臺(tái)管理系統(tǒng)之函數(shù)優(yōu)化
例如:
1)迷宮問(wèn)題
2)漢諾塔問(wèn)題

斐波那契數(shù)列
1,1, 2, 3, 5, 8, 13, 21, ....
計(jì)算第n個(gè)數(shù)是多少?

f(n)
當(dāng)n >2時(shí),f(n) = f(n-1) + f(n-2)
當(dāng)n=1或n=2時(shí), 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;
}

遞歸函數(shù)的缺點(diǎn):
性能很低?。?!

項(xiàng)目練習(xí)

1.練習(xí)1

獨(dú)立完成項(xiàng)目9

2.練習(xí)2

定義一個(gè)函數(shù),實(shí)現(xiàn)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("請(qǐng)輸入一個(gè)整數(shù): ");
    scanf("%d", &value);
    if (value < 0) {
        printf("需要大于0\n");
        return 1;
    }

    printf("%d\n", sum(value));

    return 0;
}

3.打印金字塔

打印指定類型的金字塔,用自定義函數(shù)實(shí)現(xiàn)。
效果如下:
【小白到大牛之路9】交換機(jī)后臺(tái)管理系統(tǒng)之函數(shù)優(yōu)化
代碼:

#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("請(qǐng)輸入金字塔的組成字符: ");
    scanf("%c", &c);
    if (c == '\n' || c == ' ' || c == '\t') {
        printf("請(qǐng)輸入一個(gè)非空白字符\n");
        return 1;
    }

    printf("請(qǐng)輸入金字塔的層數(shù): ");
    scanf("%d", &n);
    if (n < 1) {
        printf("層數(shù)需要大于0\n");
        return 1;
    }

    show(c, n);

    return 0;
}

4.用遞歸函數(shù)實(shí)現(xiàn)練習(xí)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("請(qǐng)輸入一個(gè)整數(shù): ");
    scanf("%d", &value);

    if (value < 0) {
        printf("需要大于0\n");
        return 1;
    }

    printf("%d\n", sum(value));

    return 0;
}

5.用遞歸函數(shù)實(shí)現(xiàn)漢諾塔

#include <stdio.h>

void hanoi(int n, char pillar_start[], char pillar_mid[], char pillar_end[]) {
    if (n == 1) {
        printf("從%s移動(dòng)到%s\n", pillar_start, pillar_end);
        return;
    }

    hanoi(n-1, pillar_start, pillar_end, pillar_mid); 
    printf("從%s移動(dòng)到%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; //盤子數(shù)

    hanoi(3, name1, name2, name3);

    return 0;
}
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI