zoukankan      html  css  js  c++  java
  • 实现一个简单的代码字计数器(一)

    前面的文章里已经介绍了如何分割字符串,博客地址在这里

    这里打算分几篇文章来写:

    互联网上有很多字计数器,但是大部分都是统计一个文本里的字数,在代码中的字计数和一段文本里的计数不太一样;比如下面的代码中计数"name"的个数,代码中单词(字)的个数是有用的;所以这篇文章里先谈一下代码字计数器的好处:

    image.png

    用处如下:首先是可以定位比较重要的对象,因为一般出现频率较高的单词可能在某个函数中比较重要。就拿我上面的代码举例子,如果逐行看下来可能并不知道我这个类想干什么,但是根据单词出现频率可以推断出是和name和address的一个类;有人会说这样并不明显,好,我们举下一个例子:

    bool CSetting::ReadValue( CRegKey &regKey, const wchar_t *valName )
    {
    // bool, int, hotkey, color
    if (type==CSetting::TYPE_BOOL || (type==CSetting::TYPE_INT && this[1].type!=CSetting::TYPE_RADIO) || type==CSetting::TYPE_HOTKEY || type==CSetting::TYPE_HOTKEY_ANY || type==CSetting::TYPE_COLOR)
    {
    DWORD val;
    if (regKey.QueryDWORDValue(valName,val)==ERROR_SUCCESS)
    {
    if (type==CSetting::TYPE_BOOL)
    value=CComVariant(val?1:0);
    else
    value=CComVariant((int)val);
    return true;
    }
    return false;
    }
    // radio
    if (type==CSetting::TYPE_INT && this[1].type==CSetting::TYPE_RADIO)
    {
    ULONG len;
    DWORD val;
    if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS)
    {
    CString text;
    regKey.QueryStringValue(valName,text.GetBuffer(len),&len);
    text.ReleaseBuffer(len);
    val=0;
    for (const CSetting *pRadio=this+1;pRadio->type==CSetting::TYPE_RADIO;pRadio++,val++)
    {
    if (_wcsicmp(text,pRadio->name)==0)
    {
    value=CComVariant((int)val);
    return true;
    }
    }
    }
    else if (regKey.QueryDWORDValue(valName,val)==ERROR_SUCCESS)
    {
    value=CComVariant((int)val);
    return true;
    }
    return false;
    }
    // string
    if (type>=CSetting::TYPE_STRING && type<CSetting::TYPE_MULTISTRING)
    {
    ULONG len;
    if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS)
    {
    value.vt=VT_BSTR;
    value.bstrVal=SysAllocStringLen(NULL,len-1);
    regKey.QueryStringValue(valName,value.bstrVal,&len);
    return true;
    }
    return false;
    }
    // multistring
    if (type==CSetting::TYPE_MULTISTRING)
    {
    ULONG len;
    if (regKey.QueryMultiStringValue(valName,NULL,&len)==ERROR_SUCCESS)
    {
    value.vt=VT_BSTR;
    value.bstrVal=SysAllocStringLen(NULL,len-1);
    regKey.QueryMultiStringValue(valName,value.bstrVal,&len);
    for (int i=0;i<(int)len-1;i++)
    if (value.bstrVal[i]==0)
    value.bstrVal[i]='
    ';
    return true;
    }
    else if (regKey.QueryStringValue(valName,NULL,&len)==ERROR_SUCCESS)
    {
    value.vt=VT_BSTR;
    value.bstrVal=SysAllocStringLen(NULL,len);
    regKey.QueryStringValue(valName,value.bstrVal,&len);
    if (len>0)
    {
    value.bstrVal[len-1]='
    ';
    value.bstrVal[len]=0;
    }
    return true;
    }
    return false;
    }
    Assert(0);
    return false;
    }
    

    这段代码是我从其他博客直接拷贝过来的一部分,是一个ReadValue函数,如果逐行读下来很有可能并不知道这段代码想表达什么,但是根据单词出现频率发现出现比较多的是"value"这个单词,所以我们可以知道这个函数的核心一定是value。然后就可以直接观看和value相关的代码,发现value第一次出现在函数内部并不是通过定义,那么由于不知道其他代码我们可以假定这个value可能是个全局变量也可能是个类;再进一步会发现value多数都是赋值操作,所以就可以推测出这个ReadValue函数的用途可能是将数据赋值到一个类成员value中。通过这种方式能比较快速的了解函数的用途。

    另一个用处是可以更好的理解输入的用途,比如在上面的ReadValue函数中,输入为regKey和valName,我们可以发现regKey和valName基本上出现次数相近而且基本是同时在使用;所以我们可以推断这两个变量很有可能是出自同一个对象的,因为2个变量需要同时进行更新。

    再有用处就是:经常出现的模式是在代码的一部分中频繁地使用单词,并且在这一部分之外很少使用。这可能意味着这部分代码集中于使用一个特定的对象,它阐明了这部分代码的职责。

  • 相关阅读:
    delphi 实体类 JSON 数组 TJsonSerializer Deserialize
    IIS 禁止访问:在 Web 服务器上已拒绝目录列表
    ASP.NET 一般处理程序
    .net 架构
    delphi XE8 NetHTTPRequest NetHTTPClient
    ASP.NET web 应用程序项目
    HttpClient
    eclipse Android 开发基础 Activity 窗体 界面
    关闭 iTunes 自动同步
    could not be installed at this time
  • 原文地址:https://www.cnblogs.com/yunlambert/p/10130903.html
Copyright © 2011-2022 走看看