技术宅,fat-man

增加语言的了解程度可以避免写出愚蠢的代码

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

函数式C代码

代码如下:

复制代码
#include <stdlib.h>
#include <stdio.h>
typedef char String[32];
typedef FILE* File;

typedef struct _Employee {
        String name;
        int age;
        int salary;
        struct _Employee *next;
} *Employee;

typedef void (*Callback)(Employee);

/* High Order Functions */
void foreach(Employee e, Callback fn) {
     Employee p;
     while (p = e) {
           e = e->next; /* Avoid *next be changed in fn */
           fn(p);
     }
}

void with_open_file(String filename, String mode, Callback fn, Employee e) {
     File file = freopen(filename, mode, (mode[0] == 'r'? stdin: stdout));
     if (file == NULL) {
        fprintf(stderr, "Cannot open %s with %s mode.\n", filename, mode);
        exit(EXIT_FAILURE);
     }
     fn(e);
     fclose(file);
}

/* Destructor */
static void employee_free_node(Employee e) {
       if (e != NULL) {
          free(e);
       }
}

void employee_free(Employee e) {
     foreach(e, employee_free_node);
}

/* Input */
static void employee_read_node(Employee node) {
       Employee e = NULL, *head = (Employee*) node;
       e = *head = (Employee)calloc(1, sizeof(struct _Employee));
       if (e != NULL && scanf("%s%d%d", e->name, &e->age, &e->salary) != 3) {
          employee_free(e);
          *head = NULL;
       }
}

void employee_read(Employee list) {
     Employee e = NULL, *head = (Employee*) list, tail = NULL;
     *head = NULL;
     while (employee_read_node((Employee)&e), e) {
           if (*head != NULL) {
              tail->next = e;
              tail = e;
           } else {
             *head = tail = e;
           }
     }
}

/* Output */
static void employee_print_node(Employee e) {
       printf("%s %d %d\n", e->name, e->age, e->salary);
}

void employee_print(Employee e) {
     foreach(e, employee_print_node);
}

/* Business Logic */
static void employee_adjust_salary_node(Employee e) {
       if (e->salary < 30000) {
          e->salary += 3000;
       }
}

void employee_adjust_salary(Employee e) {
     foreach(e, employee_adjust_salary_node);
}

int main(void) {
    Employee e = NULL;
    with_open_file("work.txt", "r", employee_read, (Employee)&e);
    employee_print(e);
    employee_adjust_salary(e);
    employee_print(e);
    with_open_file("work.txt", "w", employee_print, e);
    employee_free(e);
    return EXIT_SUCCESS;
}
复制代码

work.txt

William 35 28000
Kishore 41 35000
Wallace 37 23000
Bruce 39 18000

posted on   codestyle  阅读(258)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
历史上的今天:
2012-08-28 ubuntu下apache&php&虚拟主机开发环境配置
点击右上角即可分享
微信分享提示