精华内容
下载资源
问答
  • 20React投资组合 目录 客观 使用React创建一个更新投资组合,其中包含6个项目。 安装 (1)在VS Code中转到src文件夹或资源管理器区域,右键单击... Web Developer页面描述了六个已完成类项目。 “机械工程师”
  • 该主题是为学者设计,具有一个简单主页,其中包含一个关于部分,一个博客以及一个交互式重点部分,用于描述出版物,课程作业,所教授​​的课程和项目。 使用Bootstrap和Animate CSS进行UI设计。 兼容性...
  • :seedling: 我目前正在上关于在Cousera上进行React专门化,在Datacamp上用于数据科学家软件工程,在Udemy上部署机器学习模型全栈开发课程。 :people_with_bunny_ears: 我希望在数据科学与机器学习端到端项目上...
  • 关于 目录 用户体验(UX) 用户故事 用户故事#ID 作为一个… 我希望能够... 所以我可以…。 查看和导航 1个 购物者 浏览产品图片 选择我要购买 2 购物者 查看产品详细信息 查看价格,尺寸,IP等级,描述,评论...
  • 以下是官网https://www.tiobe.com/tiobe-index/ 对这个排名的描述 TIOBE编程社区索引是编程语言受欢迎程度的指标。索引每月更新一次。评级基于全球熟练的工程师,课程和第三方供应商的数量。诸如Google,Bing,...

    2020年11月17日15:19:22

    以下是官网 https://www.tiobe.com/tiobe-index/ 对这个排名的描述

    TIOBE编程社区索引是编程语言受欢迎程度的指标。索引每月更新一次。评级基于全球熟练的工程师,课程和第三方供应商的数量。诸如Google,Bing,Yahoo!,Wikipedia,Amazon,YouTube和Baidu等流行的搜索引擎用于计算评分。
    重要的是要注意,TIOBE索引与最佳编程语言或大多数代码行所用的语言无关。

    想知道tiobe排名有没有什么参考价值,就得知道tiobe是家做什么的公司?

    tiobe官网产品主要有两个一个是TICS测试框架,

    https://www.tiobe.com/tics/fact-sheet/

    这个主要是对代码质量进行自动化测试的工具

    https://www.tiobe.com/products/quality-assessment/

    另一个就是代码质量品控,这个应该是人工服务,主要是一些经验丰富的老程序员做技术咨询服务这样的。

    这个关于排行榜就是搜索热度,很多人用来看语言实际的应用或者活跃度排名其实是很不对的,这里的热度是指搜索引擎,一些非纯技术社区的讨论,搜索热度,注意这个不是开发社区,也不是github这类纯技术社区

    比如现在python炒的很热,所以排名就很靠前,但是实际开发应用数量就是另一回事了,我周边一些搞金融的朋友说要学python,买了两本书,放在办工桌上吃灰

    比如Visual Basic,是怎么排得这么靠前,我想主要可能是两个原因,1,excel很多脚本需要vbs,2,一些老应用需要继续迭代,写vb的太少了,很多东西需要搜索

    要说这个排名有什么实际意义吗?没有,估计是tiobe公司为了做业务吸引部分流量,做个一个营销策略而已。

    其实我更建议github,或者gitee做个开发语言热度排行榜,更有参考意义。

    https://oschina.gitee.io/gitee-2019-annual-report/

    这个gitee,但是是年度的,已经反馈给社区,常态化编程排名,季度,或者月度

    https://octoverse.github.com/

    这个是github的,通过gitee github和tiobe的对比,石锤tiobe编程语言排行榜毫无参考意义

    展开全文
  • 本人在刚开始了解Kotlin协程时候,断断续续看了网上不少文章,用长篇大论把Kotlin协程描述的非常玄乎,但是看完后还是依然云里雾里,所以决定来写一篇关于协程文章,希望能够帮助大家能够更快上手Kotlin协程 ...

    目录

    前言

    Kotlin协程,现在已经成为了面试甚至是工作中一个非常火的东西。

    本人在刚开始了解Kotlin协程的时候,断断续续看了网上不少文章,用长篇大论把Kotlin协程描述的非常玄乎,但是看完后还是依然云里雾里,所以决定来写一篇关于协程的文章,希望能够帮助大家能够更快的上手Kotlin协程

    一、Java 知识梳理

    Java&Android 基础知识梳理(0) - Java 基础知识大纲
    Java&Android 基础知识梳理(1) - 注解
    Java&Android 基础知识梳理(2) - 序列化
    Java&Android 基础知识梳理(3) - 内存区域
    Java&Android 基础知识梳理(4) - 垃圾收集器与内存分配策略
    Java&Android 基础知识梳理(5) - 类加载&对象实例化
    Java&Android 基础知识梳理(6) - 字节输入输出流
    Java&Android 基础知识梳理(7) - Android 虚拟机
    Java&Android 基础知识梳理(8) - 容器类
    Java&Android 基础知识梳理(9) - LruCache 源码解析
    Java&Android 基础知识梳理(10) - SparseArray 源码解析
    Java&Android 基础知识梳理(11) - 浅拷贝 Vs 深拷贝
    Java&Android 基础知识梳理(12) - 泛型
    Java&Android 基础知识梳理(13) - 反射

    二、Android 基础知识

    2.1 Activity 知识梳理

    Activity 知识梳理(1) - Activity 生命周期
    Activity 知识梳理(2) - Activity 栈
    Activity 知识梳理(3) - Activity 状态保存和恢复

    2.2 Fragment 知识梳理

    Fragment 知识梳理(1) - Fragement 源码解析
    Fragment 知识梳理(2) - Fragment 状态保存和恢复
    Fragment 知识梳理(3) - FragmentPagerAdapter 和 FragmentStatePagerAdapter 解析
    Fragment 知识梳理(4) - FragmentPagerAdapter 和 FragmentStatePagerAdapter 的数据更新问题

    2.3 RecyclerView 知识梳理

    RecyclerView 知识梳理(1) - 综述
    RecyclerView 知识梳理(2) - Adapter
    RecyclerView 知识梳理(3) - LayoutManager
    RecyclerView 知识梳理(4) - ItemDecoration
    RecyclerView 知识梳理(5) - ItemTouchHelper

    2.4 Loader 知识梳理

    Loader 知识梳理(1) - LoaderManager 初探
    Loader 知识梳理(2) - initLoader 和 restartLoader的区别
    Loader 知识梳理(3) - 自定义 Loader

    2.5 Android 异步任务知识梳理

    Android 异步任务知识梳理(1) - AsyncTask 解析
    Android 异步任务知识梳理(2) - HandlerThread 解析
    Android 异步任务知识梳理(3) - AsyncQueryHandler 解析

    2.6 Android 数据存储知识梳理

    Android 数据存储知识梳理(1) - SQLiteOpenHelper 源码解析
    Android 数据存储知识梳理(2) - Android存储目录
    Android 数据存储知识梳理(3) - SharedPreference 源码解析
    Android 数据存储知识梳理(4) - 数据库升级操作的处理策略

    2.7 状态栏

    Android 状态栏知识点总结

    2.8 广播

    Broadcast 知识梳理(1) - BroadcastReceiver 基本概念

    2.9 Service

    Service 知识梳理(1) - Service 问题整理

    2.10 版本适配

    Android 版本适配问题

    三、开源框架

    3.1 Retrofit 知识梳理

    Retrofit 知识梳理(1) - 流程分析
    Retrofit 知识梳理(2) - Retrofit 动态代理内部实现

    3.2 OkHttp 知识梳理

    OkHttp 知识梳理(1) - OkHttp 源码解析之入门
    OkHttp 知识梳理(2) - OkHttp 源码解析之异步请求 & 线程调度
    OkHttp 知识梳理(3) - OkHttp 之缓存基础
    OkHttp 知识梳理(4) - OkHttp 之缓存源码解析

    3.3 Volley

    Volley 知识梳理 - Volley 源码解析

    3.4 Glide

    Glide 知识梳理(1) - 基本用法
    Glide 知识梳理(2) - 自定义Target
    Glide 知识梳理(3) - 自定义transform
    Glide 知识梳理(4) - 自定义animate
    Glide 知识梳理(5) - 自定义GlideModule
    Glide 知识梳理(6) - Glide 源码解析之流程剖析

    3.5 RxJava2 理论

    RxJava 知识梳理(1) - RxJava 解析
    RxJava 知识梳理(2) - RxJava2 操作符实践
    RxJava 知识梳理(3) - RxJava2 基础知识小结

    3.6 RxJava2 实战

    RxJava2 实战知识梳理(1) - 后台执行耗时操作,实时通知 UI 更新
    RxJava2 实战知识梳理(2) - 计算一段时间内数据的平均值
    RxJava2 实战知识梳理(3) - 优化搜索联想功能
    RxJava2 实战知识梳理(4) - 结合 Retrofit 请求新闻资讯
    RxJava2 实战知识梳理(5) - 简单及进阶的轮询操作
    RxJava2 实战知识梳理(6) - 基于错误类型的重试请求
    RxJava2 实战知识梳理(7) - 基于 combineLatest 实现的输入表单验证
    RxJava2 实战知识梳理(8) - 使用 publish + merge 优化先加载缓存,再读取网络数据的请求过程
    RxJava2 实战知识梳理(9) - 使用 timer/interval/delay 实现任务调度
    RxJava2 实战知识梳理(10) - 屏幕旋转导致 Activity 重建时恢复任务
    RxJava2 实战知识梳理(11) - 检测网络状态并自动重试请求
    RxJava2 实战知识梳理(12) - 实战讲解 publish & replay & share & refCount & autoConnect
    RxJava2 实战知识梳理(13) - 如何使得错误发生时不自动停止订阅关系
    RxJava2 实战知识梳理(14) - 在 token 过期时,刷新过期 token 并重新发起请求
    RxJava2 实战知识梳理(15) - 实现一个简单的 MVP + RxJava + Retrofit 应用

    3.7 Dagger2 知识梳理

    Dagger2 知识梳理(1) - Dagger2 依赖注入的两种方式
    Dagger2 知识梳理(2) - @Qulifier 和 @Named 解决依赖注入迷失
    Dagger2 知识梳理(3) - 使用 dependencies 和 @SubComponent 完成依赖注入
    Dagger2 知识梳理(4) - @Scope 注解的使用

    四、算法知识梳理

    面试算法知识梳理(1) - 排序算法
    面试算法知识梳理(2) - 字符串算法第一部分
    面试算法知识梳理(3) - 字符串算法第二部分
    面试算法知识梳理(4) - 数组第一部分
    面试算法知识梳理(5) - 数组第二部分
    面试算法知识梳理(6) - 数组第三部分
    面试算法知识梳理(7) - 数组第四部分
    面试算法知识梳理(8) - 二分查找算法及其变型
    面试算法知识梳理(9) - 链表算法第一部分
    面试算法知识梳理(10) - 二叉查找树
    面试算法知识梳理(11) - 二叉树相关算法第一部分
    面试算法知识梳理(12) - 二叉树算法第二部分
    面试算法知识梳理(13) - 二叉树算法第三部分
    面试算法知识梳理(14) - 数字算法

    五、Kotlin 知识梳理

    Kotlin 知识梳理(1) - Kotlin 基础
    Kotlin 知识梳理(2) - 函数的定义与调用
    Kotlin 知识梳理(3) - 类、对象和接口
    Kotlin 知识梳理(4) - 数据类、类委托 及 object 关键字
    Kotlin 知识梳理(5) - lambda 表达式和成员引用
    Kotlin 知识梳理(6) - Kotlin 的可空性
    Kotlin 知识梳理(7) - Kotlin 的类型系统
    Kotlin 知识梳理(8) - 运算符重载及其他约定
    Kotlin 知识梳理(9) - 委托属性
    Kotlin 知识梳理(10) - 高阶函数:Lambda 作为形参或返回值
    Kotlin 知识梳理(11) - 内联函数
    Kotlin 知识梳理(12) - 泛型类型参数
    Kotlin 知识梳理(13) - 运行时的泛型

    六、多线程知识梳理

    多线程知识梳理(1) - 并发编程的艺术笔记
    多线程知识梳理(2) - synchronized 三部曲之基本使用
    多线程知识梳理(3) - synchronized 三部曲之锁优化
    多线程知识梳理(4) - synchronized 三部曲之等待/通知模型
    多线程知识梳理(5) - 线程池四部曲之 Executor 框架
    多线程知识梳理(6) - 线程池四部曲之 ThreadPoolExecutor
    多线程知识梳理(7) - ConcurrentHashMap 实现原理
    多线程知识梳理(8) - volatile 关键字
    多线程知识梳理(9) - ThreadLocal
    多线程知识梳理(10) - 死锁的概念
    多线程知识梳理(11) - 队列同步器实现原理 & 应用
    多线程知识梳理(12) - ReentrantLock 解析
    多线程知识梳理(13) - ReentrantReadWriteLock 原理

    最后

    这里我特地整理了一份《Android开发核心知识点笔记》,里面就包含了自定义View相关的内容

    如果你有需要的话,可以私信我【进阶】发给你

    除了这份笔记,还给大家分享 Android学习PDF+架构视频+面试文档+源码笔记,高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这几块的内容。非常适合近期有面试和想在技术道路上继续精进的朋友。

    如果你有需要的话,可以点击我的GitHub免费获取!

    分享上面这些资源,希望可以帮助到大家提升进阶,如果你觉得还算有用的话,不妨把它们推荐给你的朋友~

    4%B8%8D%E4%BC%9A%E8%BF%99%E4%BA%9B%EF%BC%9F%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md)**

    [外链图片转存中…(img-XTQx6KJ9-1614432784969)]

    分享上面这些资源,希望可以帮助到大家提升进阶,如果你觉得还算有用的话,不妨把它们推荐给你的朋友~

    喜欢本文的话,给我点个小赞、评论区留言或者转发支持一下呗~

    展开全文
  • 问题描述:银行储蓄系统的设计与实现 ...除了下面的系统基本功能的描述外,鼓励开展调研,使开发的软件尽量符合实际的银行储蓄系统的实际业务要求。可以参考8.1节中关于选用合适的数据结构的讨论,确定数据存储的
    问题描述:银行储蓄系统的设计与实现
    模拟银行柜台业务的要求,实现一个小型的“银行储蓄系统”软件的开发,其中包括开户、存款、取款、转账、改密、挂失、解挂、销户等功能。
    在开发过程中,请按照问题求解过程的要求,体验开发过程中需要做的工作。除了下面的系统基本功能的描述外,鼓励开展调研,使开发的软件尽量符合实际的银行储蓄系统的实际业务要求。可以参考8.1节中关于选用合适的数据结构的讨论,确定数据存储的方案。
    要求在程序运行过程中或程序运行结束之前,将业务发生的数据保存到文件中,并在下次运行时能从文件中读出数据,使业务能够在继续在原先的基础上开展。可以使用文本文件也可以使用二进制文件。
    根据模块化程序设计的要求,将各功能设计成独立的函数实现。必要时,提取出公共的功能设计专门的函数,作为支持各函数中的子功能要调用的模块。建议设计“菜单”式的操作界面,方便用户使用。
    各功能的要求如下:
    (1)开户:增加一个银行账户,输入账号、姓名、密码、金额、状态自动置为0(正常)。建议输入密码的过程中,以(*)代替实际输入的符号显示出来(实现方法请利用搜索引擎获取帮助)。作为对密码的设置,在输入一次密码后,需要再次输入密码,两次输入一致后,才保存并接受。由于设置了密码,其他业务必须在输入的账号,密码均正确时才能继续。
    (2)存款:输入账号、金额,增加该账号的余额。
    (3)取款:输入账号、金额,减少取款后的余额。要求取款额不能超过原余额。
    (4)查询:输入账号,显示账户信息。
    (5)转账:输入转入的账号、金额以及转入的账户,减少转出账户的余额,增加转入账号的余额。要求转出账户的金额不能超过该账号的余额,转出减少的金额,与转入账户增加的金额相同。
    (6)挂失:输入账号,将其状态改为1(挂失)。处于挂失状态的账号,不能执行除解挂以外的其他任何操作。
    (7)解挂:将状态为1(挂失)的账户的状态改为0(正常)
    (8)销户:输入账号,确认后,提示将余额全部取完,将余额置为0,并将状态state置为2(销户)。办理后销户的账号,不能再执行除查询外的功能。
    作者;何知令

    发表时间:2017年4月19日

    代码:

    /*
    问题描述:银行储蓄系统的设计与实现
    模拟银行柜台业务的要求,实现一个小型的“银行储蓄系统”软件的开发,其中包括开户、存款、取款、转账、改密、挂失、解挂、销户等功能。
    在开发过程中,请按照问题求解过程的要求,体验开发过程中需要做的工作。除了下面的系统基本功能的描述外,鼓励开展调研,使开发的软件尽量符合实际的银行储蓄系统的实际业务要求。可以参考8.1节中关于选用合适的数据结构的讨论,确定数据存储的方案。
    要求在程序运行过程中或程序运行结束之前,将业务发生的数据保存到文件中,并在下次运行时能从文件中读出数据,使业务能够在继续在原先的基础上开展。可以使用文本文件也可以使用二进制文件。
    根据模块化程序设计的要求,将各功能设计成独立的函数实现。必要时,提取出公共的功能设计专门的函数,作为支持各函数中的子功能要调用的模块。建议设计“菜单”式的操作界面,方便用户使用。
    各功能的要求如下:
    (1)开户:增加一个银行账户,输入账号、姓名、密码、金额、状态自动置为0(正常)。建议输入密码的过程中,以(*)代替实际输入的符号显示出来(实现方法请利用搜索引擎获取帮助)。作为对密码的设置,在输入一次密码后,需要再次输入密码,两次输入一致后,才保存并接受。由于设置了密码,其他业务必须在输入的账号,密码均正确时才能继续。
    (2)存款:输入账号、金额,增加该账号的余额。
    (3)取款:输入账号、金额,减少取款后的余额。要求取款额不能超过原余额。
    (4)查询:输入账号,显示账户信息。
    (5)转账:输入转入的账号、金额以及转入的账户,减少转出账户的余额,增加转入账号的余额。要求转出账户的金额不能超过该账号的余额,转出减少的金额,与转入账户增加的金额相同。
    (6)挂失:输入账号,将其状态改为1(挂失)。处于挂失状态的账号,不能执行除解挂以外的其他任何操作。
    (7)解挂:将状态为1(挂失)的账户的状态改为0(正常)
    (8)销户:输入账号,确认后,提示将余额全部取完,将余额置为0,并将状态state置为2(销户)。办理后销户的账号,不能再执行除查询外的功能。
    作者;何知令
    发表时间:2017年4月19日*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #define upNum 100
    int choice;//选择功能使用
    char ch;
    FILE *fp,*Fp;//文件指针,用于打开文件读和写
    int i;//循环计数
    int k;
    char key[6];//密码输入存储
    double money;//用于金钱的相关输入
    int num;
    typedef struct//用户信息存储
    {
        int num;
        char name[10];
        char key[6];
        double money;
        int state;//账户状态解读:设定state值为-1时为未开户的银行卡,0为正常状态,1为挂失,2为冻结
    } USER; //用户信息存储
    USER user[upNum];//upNUm个结构体
    /*改变用户账户状态函数*/
    void start_new();
    void change_state(int num,int change);
    void save(int num);
    void draw(int num);
    void new_user();
    int key_pass();
    void change_key(int num);
    void seek(int num);
    void transfer(int num);
    void lost(int num);
    void bake(int num);
    void close(int num);
    void pass();
    int search(int n);
    void old_user();
    int strcomp(char s1[],char s2[]);
    int judge_state(int num);
    void change_state(int num,int change)
    {
        user[num].state=change;
    }
    /*开启新用户函数*/
    void start_new()
    {
        printf("系统已分配一个账户给您\n");
        for(i=0; i<upNum; i++)//从结构体中找到一个状态为未开户的账户
        {
            if(user[i].state==-1)
                break;
        }
        num=user[i].num;
        printf("卡号为%d\n",num);
        printf("请输入姓名:\n");
        scanf("%s",user[num].name);
        while(1)
        {
            printf("请输入你的密码(六位数字):\n");
            pass(key);
            printf("\n请确认您的密码:\n");
            pass(user[num].key);
            if(strcomp(key,user[num].key))
            {
                printf("\n您的(新)密码为%s\n",user[num].key);
                break;
            }
        }
        printf("请输入金额(金额不超过1千万):\n");
        while(1)
        {
            scanf("%lf",&money);
            if(money<10000000)//单笔存款金额限制
                break;
            else
                printf("单次存款金额不得超过1千万,请重新输入\n");
        }
        user[num].money=money;
        user[num].state=0;
        printf("恭喜您,您的账户已开通\n");
    }
    /*用于输入密码*/
    void save(int num)
    {
        int ok=0;
        ok=judge_state(num);
        if(ok==0)
            return;
        printf("请输入存款金额:\n");
        scanf("%lf",&money);
        user[num].money+=money;
        printf("您的余额为%.2f\n",user[num].money);
    }
    /*用于取款*/
    void draw(int num)
    {
        int ok=0;
        ok=judge_state(num);
        if(ok==0)
            return;
        printf("请输入取款金额:\n");
        scanf("%lf",&money);
        if(user[num].money<money)
        {
            printf("抱歉,您余额不足,请选择重新输入(输入1)或返回主界面输入(除1任意键):\n");
            scanf("%d",&choice);
            if(choice==1)
                draw(num);
            else
                return;
        }
        else
        {
            user[num].money-=money;
            printf("您的余额为%.2f\n",user[num].money);
        }
    }
    /*密码验证界面*/
    int key_pass()
    {
        int time=3;
        int ok=0;
        if(time==3)
            pass(key);
        while(1)
        {
            if(strcomp(key,user[num].key))
            {
                printf("\n输入正确\n");
                ok=1;
            }
            else
            {
                time--;
                if(time==0)
                    break;
                printf("\n输入错误,你还有%d次输入机会\n",time);//密码输入错误三次将冻结账号
                printf("返回主菜单请输入0,继续输入密码请输入1\n");
                scanf("%d",&choice);
                if(choice==0)
                    return time;
                else if(choice==1)
                {
                    printf("请输入您的密码\n");
                    pass(key);
                }
            }
            if(ok==1||time==0)
                break;
        }
        return time;
    }
    /*用于输入新密码或更改密码*/
    void change_key(int num)
    {
        while(1)
        {
            printf("请输入您的原密码:\n");
            key_pass(num);
            printf("请输入您的新密码(六位数字):\n");
            pass(key);
            printf("\n请确认您的密码:\n");
            pass(user[num].key);
            if(strcomp(key,user[num].key))
            {
                printf("\n您的(新)密码为%s\n",user[num].key);
                break;
            }
            else
                printf("\n两次输入不一致,请重新输入\n");
        }
    }
    /*账户余额查询界面*/
    void seek(int num)
    {
        printf("您的余额为%.2f\n",user[num].money);
        printf("取卡请输入0,返回主菜单请输入1\n");
        scanf("%d",&choice);
        if(choice==0)
            exit(-1);
        else if(choice==1)
            return;
    }
    /*转账界面*/
    void transfer(int num)
    {
        int S_num;
        int ok=0;
        printf("请输入转入的账号\n");
        scanf("%d",&S_num);
        ok=judge_state(S_num);
        if(ok==1)
        {
            printf("请输入金额:\n");
            scanf("%lf",&money);
            if(money>user[num].money)
            {
                while(1)
                {
                    printf("您的余额不足,请选择重新输入(1)或存款(2)\n");
                    scanf("%d",&choice);
                    if(choice==1)
                        scanf("%lf",&money);
                    if(money<user[num].money||choice==2)
                        break;
                }
                if(choice==2)
                    save(num);
            }
            else
            {
                user[num].money-=money;
                user[S_num].money+=money;
                printf("转账成功\n");
                printf("您的户余额为%.2f",user[num].money);
                printf("请按任意字符键返回上层\n");
                scanf("%d",&choice);
                return ;
            }
        }
    }
    /*挂失界面*/
    void lost(int num)
    {
        user[num].state=1;
        printf("挂失成功\n");
        printf("请按任意键返回上层\n");
        scanf("%d",&choice);
        return ;
    }
    /*解挂界面*/
    void bake(int num)
    {
        user[num].state=0;
        printf("解挂成功\n");
        printf("请按任意键返回上层\n");
        scanf("%d",&choice);
        return ;
    }
    /*判断当前账号状态界面,返回值返回用户账户状态*/
    int judge_state(int num)
    {
        for(i=0; i<upNum; i++)
        {
            if(num==user[i].num)
            {
                if(user[i].state==0)
                {
                    printf("账户状态正常\n");
                    break;
                }
                if(user[i].state==-1)
                {
                    printf("您所输入的账号不存在或已销户\n");
                    return 0;
                }
                if(user[i].state==1)
                {
                    printf("您所输入的账号已挂失,不能进行操作\n");
                    return 0;
                }
                if(user[i].state==2)
                {
                    printf("您所输入的账号已冻结,不能进行操作\n");
                    return 0;
                }
            }
        }
        return 1;
    }
    /*销户界面*/
    void close(int num)
    {
        user[num].state=-1;
        user[num].money=0;
        printf("销户成功\n");
        printf("请按任意键返回上层\n");
        scanf("%d",&choice);
        return ;
    }
    /*用于输入密码*/
    void pass(char a[])
    {
        for(i=0; i<6;)
        {
            ch=getch();
            if(ch=='\r')
                break;
            if(ch>='0'&&ch<='9')
            {
                a[i]=ch;
                putchar('*');//密码输入时输出*号
                i++;
            }
            else
            {
                printf("\n密码不应含字符,请重新输入\n");
                i=0;
            }
            if(i==6)
                break;
        }
        a[6]='\0';
    }
    /*寻找账户所在结构体下表*/
    int search(int n)
    {
        for(i=0; i<upNum; i++)
        {
            if(i==n)
                return i;
        }
        return 0;
    }
    /*老用户主界面*/
    void old_user()
    {
        int is_pass;
        int account;
        printf("请输入你的账户:\n");
        scanf("%d",&account);
        for(i=0; i<upNum; i++)
        {
            if(account==user[i].num)
            {
                if(user[i].state==0)
                {key_pass(num);
                    printf("账户状态正常\n");
                    break;
                }
                if(user[i].state==-1)
                {
                    printf("您所输入的账号不存在或已销户\n");
                    return;
                }
                if(user[i].state==1)
                {
                    printf("您所输入的账号已挂失,如若是本人操作,请前往解挂界面解挂\n");
                    break;
                }
                if(user[i].state==2)
                {
                    printf("您所输入的账号已冻结,如若是本人操作,请前往解冻界面解冻\n");
                    break;
                }
            }
        }
        printf("请输入你的密码:\n");
        is_pass=key_pass();
        if(is_pass==0)
        {
            change_state(account,3);//3为冻结状态
            printf("抱歉,您密码连续输入错误三次;,若是您本人操作请携带身份证前往柜台解冻\n");
            return;
        }
        printf("\n");
        while(1)
        {
            printf("1:存款\n2:取款\n3:查询\n4:转账\n5:挂失\n6:解挂\n7:销户\n8:改密\n0:退出\n");
            printf("请输入想进行的操作:\n");
            scanf("%d",&choice);
            switch(choice)
            {
            case 1:
                save(account);//存款3456
                break;
            case 2:
                draw(account);//取款
                break;
            case 3:
                seek(account);//查询
                break;
            case 4:
                transfer(account);//转账
                break;
            case 5:
                lost(account);//挂失
                break;
            case 6:
                bake(account);//解挂
                break;
            case 7:
                close(account);//销户
                break;
            case 8:
                change_key(account);//改密
                break;
            }
            if(choice==0)
                break;
        }
    }
    /*比较输入密码是否正确*/
    int strcomp(char s1[],char s2[])
    {
        for(i=0; i<6; i++)
        {
            if(s1[i]!=s2[i])
                return 0;
        }
        return 1;
    }
    /*主界面*/
    int main()
    {
        if((fp=fopen("bank.txt","r"))==NULL)//从文件中提取出用户数据
        {
            printf("cannot open bank.txt!");
            exit(1);
        }
        for(i=0; i<upNum; i++)//若文件未进行初始化,初始化结构体,并在程序结束时将结构体存入文件
        {
            user[i].num=i;
            user[i].money=0;
            user[i].state=-1;
        }
        for(i=0; i<upNum; i++)//从文件总读入数据
            fscanf(fp,"%d %s %s %lf %d",&user[i].num, user[i].name, user[i].key, &user[i].money,&user[i].state);
        fclose(fp);
        while(1)
        {
            printf("*********************************************\n");
            printf("开户请输入1,或输入2对已有账号进行操作,退出输入0\n");
            scanf("%d",&choice);
            if(choice==1)
                start_new();//开户
            else if(choice==2)
                old_user();//老用户
            else if(choice==0)
                break;
        }
        if((Fp=fopen("bank.txt","w"))==NULL)//从文件中提取出用户数据
        {
            printf("cannot open bank.txt!");
            exit(1);
        }
        for(i=0; i<upNum; i++)//将结构体中的数据写入文件
            fprintf(Fp,"%d %s %s %f %d\n",user[i].num, user[i].name, user[i].key, user[i].money,user[i].state);
        fclose(Fp);
        return 0;
    }
    
    程序运行结果展示:

    知识点总结:文件与结构体

    学习心得:做了很久也改了很久,还是不完美,也就这样作罢


    展开全文
  • 在这里,您将找到与在上From Dev to DevOps Wizard课程有关所有内容。 描述 有人告诉您,现在需要在Kubernetes上部署应用程序,但是从哪里开始呢? 您来对地方了。 起初,Kubernetes可能非常吓人。 特别是如果您...
  • 达芙妮网站开发

    2011-10-27 23:46:54
    课程设计,开发了一个关于鞋子的网站,对网站做了详细的描述
  • Unity游戏开发对象池

    千次阅读 2015-08-26 21:17:07
    关于对象池的免费脚本和教程比比皆是,甚至unity官方也在实战训练课程中讲过。他们的描述介绍虽然很精彩,但我不准备直接使用它。在这篇文章中,我将分享对Unity官方实现的看法,以及如何去改进它。 Unity Live ...

    Unity游戏开发中的对象池

    对象池在游戏中相当常用。通过对GameObject的反复利用,而不是摧毁之后再重建,能节约宝贵的CPU资源。关于对象池的免费脚本和教程比比皆是,甚至unity官方也在实战训练课程中讲过。他们的描述介绍虽然很精彩,但我不准备直接使用它。在这篇文章中,我将分享对Unity官方实现的看法,以及如何去改进它。

    Unity Live Training

    对象池的实战训练由Mike Geig 提供,点这里—UnityLive Training demo。我个人不了解Mike,但一般来说我认为,如果一个人在Unity网站上整理内容,作为一个专业人士,他必须满足一些最低水平的标准。我搜索了下,发现他是作家同时也是一名大学讲师。对我来说足够了!如果你还没看过这视频,那就去看吧—视频里对于这次的主题的介绍很棒。视频时长49分钟,然而其中并没有明显的让你拷贝他代码的地方,所以如果你只是为了代码而跳过视频,我在下面提供了一个示例仅供参考。他的demo可以归纳为以下三个基础脚本:

    一段时间后回收一颗子弹的脚本
    迅速地发射子弹(从对象池中重用)的脚本
    管理对象池的脚本


    using UnityEngine;
    using System.Collections;
    public class BulletDestroyScript : MonoBehaviour 
    {
        void OnEnable ()
        {
            Invoke("Destroy", 2f);
        }
        void Destroy ()
        {
            gameObject.SetActive(false);
        }
        void OnDisable ()
        {
            CancelInvoke("Destroy");
        }
    }

    using UnityEngine;
    using System.Collections;
    public class BulletFireScript : MonoBehaviour 
    {
        public float fireTime = 0.05f;
        void Start ()
        {
            InvokeRepeating("Fire", fireTime, fireTime);
        }
        void Fire ()
        {
            GameObject obj = ObjectPoolerScript.current.GetPooledObject();
            if (obj == null)
                return;
            // Position the bullet
            obj.SetActive(true);
        }
    }

    子弹的发射及回收脚本在这里其实并不那么重要——这只是如何使用“对象池系统”的一个例子。
    ObjectPoolerScript 脚本非常重要,有几个改进的地方我想强调一下。

    第一个是可重用性。脚本本身就包含在其组件中以便重复使用,但目前看来只能在不同项目间重用。然而我想说更重要的是,它在同一个项目中,是不可重用的。这就是为什么该脚本只引用了一个预制件。如果你想在池中保存不同类型的子弹,道具以及敌人等等,你需要在每一个物体上面放一个新脚本。请注意你不能简单地多次添加该组件并分配不同的预制件,因为有些类使用了单例设计模式。最后调用Awake的脚本拥有静态类的引用“current”,。没有很好的方法找到其它实例或者将它们区分开来。

    我很喜欢这个可以预填充对象池的系统,我也喜欢它能在需要时扩充。我们可以添加一个小功能,就是说它允许生成多少。某些情况下指定一个最大值会比较好。

    下一个改进是关于一个物体如何被认为“已入池”或“未入池”是基于它的GameObject是否为激活状态(active)。造成这个疑问的原因有很多,例如:

    对象在分配给用户时并不处于激活状态,所以也没办法知道用户何时会激活这个物体。这就意味着对象池很可能错误地将同一个物体分配给多个用户。
    因为对象池正在检查层次面板中的激活状态,禁用任何父物体都将导致已入池对象被标记为可重用—这可能会导致不可预期的后果。
    必须检查整个层次结构来判断一个物体是否可用—要比在某些位置保存bool值慢得多。

    这个方法从不检查它已入池物体的有效性。例如,你有一个对象池,用户使用一个对象并把它作为另一个物体的父物体,然后父物体被销毁,你不可能从销毁中保存已入池对象。池管理器将在它下一次检查被摧毁物体索引的时候崩溃。在一个系统中,把一个物体从一个池中拿出再放进去,池可以选择不添加空(null)物体,因而从一定程度上保证安全。

    我自己的池化通过一个队列来实现,它会自然地从它自己的集合中添加或移除对象。

    这个特殊的问题是由Mike提出的坏主意。他表示从集合中移除和插入对象“实在是太昂贵了”甚至回答说使用两个不同的list,这样就不需要寻找返回一个可接受的对象。他的回答大致上是在说,“查找比管理两个不同的list更有效率”。

    我第一个反应是“啊哈?!”,他实现的查找系统在某处的时间复杂度介于O(1) 与 O(n)之间,这取决于多快能找到一个有效的重用对象,我们只能说平均复杂度将会是O(n/2)。不管系统多大,队列中的入列和出列方法都是O(1)的时间复杂度。即使你使用两个List去管理,只要不改变长度Add 操作就是O(1)的复杂度,你还能以O(1)时间复杂度将它从list的最后移除。

    小贴士:

    O(1) 和O(n) 是大O符号表达式,用来表示算法在接收输入后的执行时间(即算法时间复杂度)。O(1) 表示恒定时间——变快的唯一方法就是什么也不做。O(n) 表示线性时间——系统越大,过程越慢。

    我的下一个想法是,不管它的容量有多大,即使从队列中增删一些对象,依然能保持它的速度,但这并不一定意味着快。也许Mike知道一些我不知道的东西—我想很有可能像他的例子一样的基于对象池的小型搜索实际上要比在对象集合中移除、再加入快。所以我决定亲自彻底检验一下。我新建了一个工程,并加入了一个创建了两种类型对象池的脚本:一个池保存一个固定的对象集合,并且根据需要寻找一个有效的匹配。第二个池保存一个可以添加删除不需要搜索的可入池物体的队列。最大的问题在于,搜索或者修改集合最终都会更加耗时。

    在Mike的demo中,为了使得在发射能力上没有任何差距,一个宇宙飞船需要大约41个在对象池中的子弹。因为Mike也提出,池可以为其他角色重用(敌人等等),而池中存放100个子弹也没什么不合理的。因此,我创建了100个子弹,并循环1000次,每次循环都得到并“使用”所有池中对象,再将它们返回池中。我使用System.Diagnostics.Stopwatch来测算每次测试所需的时间,并将结果输出到控制台。两个测试都能很快地执行,但是,测试结果对我有利——必须搜索list要比队列系统中在对象的集合中实际地增加移除对象慢了大约4倍的时间。

    SearchPool 完成:128 ms
    QueuePool 完成:31ms

    任何想自己测试或验证我的测试是否公平公正的人,都可以查看下面的代码。另外,根据这些测试结果,我认为没有理由因为他的警告而忽视我的实现方法。

    我的实现

    不是根据对象是否激活来决定该对象是否可以入池,我决定另外添加一个带有bool值的组件来帮我指明。比起一个基于GameObject激活标志作为入池判断的系统来说,这更灵活也更安全。

    using UnityEngine;
    using System.Collections;
    public class Poolable : MonoBehaviour 
    {
        public string key;
        public bool isPooled;
    }

    你也许已经注意到了在我Poolable里有一个key。这是因为我想让系统能重用于多种不同的对象,而不用为每一个对象另外创建新的池管理器。我的控制器,简单来说,有一个从字符串 key 映射到PoolData类的字典,它包含了以下信息:用于实例化新对象的预制,内存中保存的最大对象数量,以及用于存储可重用对象的队列。要使用它,你首先要调用AddEntry方法,在其中指定key与prefab的映射,并且告诉它预先创建多少(如果有)对象以及要存入内存的最大对象数量。在理想情况下,你会知道在游戏中平均需要多少对象。因为你可以在原始群体和最大计数中使用不同的值。你对池的是否扩充,扩充多少,有着完全控制权。


    我使用的这个方法是静态的——这就意味着你并不需要一个实例引用来使用池管理器,你只需引用该类本身,静态方法比实例方法和属性要稍微快一点。但同时你也失去了一些灵活性比如继承和重载某些功能性函数。选择最适合你需求的模式。


    即使我是用了静态方法,我仍然选择去创建一个单例实例,我使用这个GameObject有以下两个原因,有兴趣的可以关注一下:


    组织结构:通过使池化物体成为池管理器的子物体,我能在编辑器的层次面板(Hierarchy)中折叠它们,这样开发真是棒极了!
    保存物体:我的池管理器能保存场景改动,还可以保存其层次中的已入池对象。如果你不想要这功能,只需在销毁已添加实体的脚本同时销毁该实体即可。否则,如果你在多个场景中重用物体,或者在一个场景中来回反复地改变,那么这些场景的后续加载时间将会不一样长。


    Demo

    我创建了一个小demo来测试池管理器,并验证一切都按照我期望的那样运作。我创建了两个场景(确保在build setting里加入了它们),分别在一个对象(场景相机)上关联了我的Demo脚本。我改变了其中一个场景的背景,以便明显区分场景的改变。我也使用了OnGUI,所以无需另外设置该脚本。我只是简单地创建了一个Sphere作为脚本中的预制。

    这个demo在屏幕上显示了四个按钮,前两个可以切换场景来确认池管理器及其保存的已入池对象。后两个按钮可以在池中添加或删除对象。请注意,如果你只在原始容量内出入对象池,那么不需创建新对象。如果你从队列中出去的数量比初始的数量多,那将会新建对象来填满空缺,但是在池中只保存指定最大数量的对象。举个例子,如果指定初始数量为10,最大数量为15,然后出列20个,将会另外新建10个对象,但是在入列时,只有其中的5个对象会被储存在池中,另外5个将会被摧毁。

    我不会在实际项目中使用OnGUI—而是使用ugui来代替。但是,为了快速演示的目的,OnGUI非常方便,因为全部的设置都可以在一个脚本中完成,然而ugui却需要设置各种如Canvas,Panels,Button,以及通过接口连接事件等等。

    总结

    本文探索了对象池的主题以及如何写一个自定义的池化管理器。我分享了我在Unity实战训练课程中对对象池demo的想法并指出了我觉得需要提升的地方。我挑战了查找对象池要比添加和删除池中对象更高效的说法,并且我给出了两个测试及其测试结果评估。最后我展示了我自己的实现方法,一种更灵活,更安全,重用性及效率更高的方法。


    转载于:游戏蛮牛 http://www.unitymanual.com/


    ===================================================================================
    结束。


    展开全文
  • 这次的课程设计将我们这学期所学数据库理论知识用到具体实践中去,深化了理论知识,同时也锻炼了我们动手实践能力,有了以前练习为前提做起来也比较顺利。不过在具体实践时候还是遇到了一些小...
  • 编程开发进阶更重要是掌握核心设计思维[图]: “单独写一个琐碎代码块就等同于弹奏音阶一样,不幸是,弹奏音阶并不能教会你任何关于音乐东西,并且非常枯燥” 这是 Eric S. Raymond 在他文章《How to ...
  • 我将展示我在UFSC毕业时开发的项目,该知识库将专注于有关编程语言的类项目。 我将在博客中发布有关课程本身的信息。 我将按学期分开 课堂上开发的项目 第一学期 编程逻辑 第二学期 编程语言I 第三学期 C中的数据...
  • 画数据流图和用例图某高校欲开发一个成绩管理系统,记录并管理所有选修课程的学生平时成绩和考试成绩,其主要功能描述如下:1.每门课程都有3到6个单元构成,每个单元结束后会进行一次测试,其成绩作为这门课程的...
  • neo4j是一个正在被使用和开发的语言。 neo4j有下面几个特点: 他的查询语言是Cypher。 Cypher 介绍:作为Neo4j的查询语言,“Cypher”是一个描述性的图形查询语言,允许不必编写图形结构的遍历代码对图形存储有...
  • 目录 1.说明 2.模型类的设计 3.代码的具体实现 4.详情地址 关于作者 @ 1.说明 models是django的很重要的...本文章的所研究项目为黑马教育python课程中的项目实战-天天生鲜项目 这里就简单的描述下,...
  • 我们是开发人员,当我们想让客户告诉我们他们想法时不能奢求他们能用专业语言描述出来,所以在开发人员与客户之间连接人,项目经理应运而生。与客户交流也是一门重要的课程,应该好好学习其中道理。 在做一...
  • Fasecure是在慕尼黑工业大学的高级实践课程“以IBM Power AI为例的机器学习应用挑战”的背景下开发的。 我们的主要任务是建立一个完整的面部识别系统。 人脸识别管道 该项目的主要重点是面部识别的实现。 为此,...
  • 近期在学习一个AB包生成和加载框架,里面有一部分关于配置表的课程。于是把这部分单独拿出来,并且进行了一定修改,以巩固学习到知识。这里记录一下框架中用到知识(相关类以及用法)。 C#中反射 1.基本...
  • 本报告是关于航班信息查询系统,包括技术点有二分查找、基数排序、顺序查找,C++开发,目录如下 摘要 3 第一章 绪论 4 1.1课程设计选题 4 1.1.1选题描述 4 1.1.2选题要求 4 第二章 系统需求分析 4 2.1输入/输出...
  • 数据库课程设计(基于B/S)

    热门讨论 2008-12-28 15:28:06
    ①原则1 (确定实体):能独立存在事物,例如人、物、事、地、团体、机构、活动、事项等等,在其有多个由基本项描述的特性需要关注时,就应把它作为实体。 ②原则2 (确定联系):两个或多个实体间关联与结合,...
  • 数据结构(C#语言描述)

    2011-09-15 19:44:51
    所以说,用C#语言来讲授《数据结构》课程是我院专业改革结果。而用C#语言写数据结构教材目前国内基本上是空白。鉴于此,编者决定写本书。 在接下来写作过程中,编者遇到了另外一个问题,那就是C#语言和.NET ...
  • 00-学前须知 P1-为什么要学习数据结构与算法 P2 -编程语言选择 在这里插入图片描述 P3-课程大纲 P4-注意事项 P5-关于课程的选择
  • 此需求规格说明书对《学生信息系统》软件做了全面细致的用户需求分析,明确所要开发的软件应具有的功能、性能与界面,使系统分析人员及软件开发人员能清楚地了解用户的需求,并在此基础上进一步提出概要设计说明书和...
  • iPhone开发秘籍(第2版)--源代码

    热门讨论 2012-12-11 13:51:22
     《iphone开发秘籍(第2版)》提供了关于iphone sdk以及iphone开发的全面信息,对iphone sdk中的各种组件做了深入浅出的介绍,包括iphone 3.0 sdk的所有新增特性,同时对iphone开发的基本流程、基本原理和基本原则...
  • iPhone开发秘籍(第2版)--详细书签版

    热门讨论 2012-12-11 13:42:25
     《iphone开发秘籍(第2版)》提供了关于iphone sdk以及iphone开发的全面信息,对iphone sdk中的各种组件做了深入浅出的介绍,包括iphone 3.0 sdk的所有新增特性,同时对iphone开发的基本流程、基本原理和基本原则...
  • 1.2 关于图书借阅管理系统几个误区.......................................................………….........2 1.3 系统开发所用技术准备.....................................................................
  • 本人在刚开始了解Kotlin协程时候,断断续续看了网上不少文章,用长篇大论把Kotlin协程描述的非常玄乎,但是看完后还是依然云里雾里,所以决定来写一篇关于协程文章,希望能够帮助大家能够更快上手Kotlin协程 ...
  • 关于ds18b20程序

    2009-05-05 18:01:55
    //使温度值写入相应wendu[i]数组中----- for(ii = i; ii > 0; ii--) { p_wendu++; } i++; if(i > 4) i = 0; //------------------------------------- //温度正负数处理----------------------- // //-------...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 181
精华内容 72
关键字:

关于课程开发的描述