发布新日志

  • Google Protocol Buffer

    2011-03-14 21:36:38

    Protocol Buffer是 Google 公司針對結構化的數據制定的一個比 XML 傳輸速度更快的一種標記文本格式, 它能使用 Google 已經公布出來的一些源程式及 API 進行快速處理封裝, 并且進行二進制序列化後內容會變得非常少,解封包的速度也非常快. 在應用程序的參數設定/配置 ,簡單數據或者固定格式數據的封裝傳送上,它會比XML方便應用. 當然, 畢竟XML已經成為了多種行業標準的編寫工具, Protocol Buffer 還只是google 公司內部使用的一個比較優秀的數據處理辦法, 在通用性上肯定會有天差地別. Protocol Buffer 在處理大量未知結構的內容, 或者對指定結構的數據進行 顯示格式化時會比較吃力. 因為我目前致少還沒看到它在這方面提供的功能.下面是一段  Protocol Buffer 對指定結構數據的定義示例:

    message Person {  

        required string name = 1; 

        required int32 id = 2; 

        optional string email = 3; 

     

        enum PhoneType { 

            MOBILE = 0; 

            HOME = 1; 

            WORK = 2; 

        } 

     

        message PhoneNumber { 

           required string number = 1; 

           optional PhoneType type = 2 [default = HOME]; 

        } 

        repeated PhoneNumber phone = 4; 

    }

    下面是對上述數據結構進行調用/輸出/序列化 的C++程序示例:

    Person person; 

    person.set_name("John Doe"); 

    person.set_id(1234); 

    person.set_email("jdoe@example.com"); 

    fstream output("myfile", ios::out | ios::binary); 

    person.SerializeToOstream(&output);

    輸入/以字符串導入的C++程序示例:

    Person person; 

    person.set_name("John Doe"); 

    person.set_id(1234); 

    person.set_email("jdoe@example.com"); 

    fstream output("myfile", ios::out | ios::binary); 

    person.SerializeToOstream(&output);

    從上面的例子我們可以看到, Protocol Buffer實際上就是 C++裡面的一個結構型, 所以它的運行速度比起 XML文件會快上非常大的倍數.  因為XML 需要從文件中讀取出字符串,再轉譯成 XML 文檔對象結構模型, 然後再從XML 文檔對象結構模型中讀取出指定節點的字符串, 最後再將這個字符串轉換成指定類型的變量, 這樣繁複的處理, 將大大消耗 CPU 資源. 而Protocol Buffer只需要簡單地將一個二進制序列, 按照指定的格式讀取到 C++ 結構類型中去就行了.


  • 【C++】前置声明

    2011-01-13 15:52:30

    类或结构体的前向声明只能用来定义指针对象或引用,因为编译到这里时还没有发现定义,不知道该类或者结构的内部成员,没有办法具体的构造一个对象,所以会报错。
    将类成员改成指针就好了。

    相关的编译错误:

    编译错误一:XX does not name a type
    编译错误二:field `XX' has incomplete type

    编译错误一:
    XX does not name a type, 中文意思为“XX没有命名一个类型“
    拿个例子来讲,如果两个类定义如下:
    class B{
    public:
    B(){}
    ~B(){}

    private:
    A a;
    };

    class A{
    public:
    A(){}
    ~A(){}

    private:
    int a;
    };

    编译成则将报一个error:"A does not name a type"
    报错的位置为红色那一行。

    即使clase A和class B分别在两个文件定义,并且在定义B的文件头中#include了class A的头文件也同样会报这个错(这是因为编译和链接之间的先后关系造成的)。

    解决该错误的办法:
    在class B定义声明之前先声明一下class A, 如下:
    class A;
    class B{
    public:
    B(){}
    ~B(){}

    private:
    A a;
    };

    class A{
    public:
    A(){}
    ~A(){}

    private:
    int a;
    };

    参考:http://hi.baidu.com/funrole/blog/item/325e1825967f7b6934a80f9c.html

  • 【C++】vs2008设置include与lib的方法

    2010-12-28 15:51:49

    tools-->options--->projects and solutions-->VC++ directoris 然后在show directoris for 中选择 :

    include files,并添加路径

    Library files,并添加路径

  • 【php】php中的一些常量以及获取当前类名函数名的方法

    2010-12-01 11:16:17

    1.获取行号、文件路径文件名、类名、方法名的常量
    __LINE__     文件中的当前行号。
    __FILE__    文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。
    __FUNCTION__    函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
    __CLASS__    类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
    __METHOD__    类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。

    注:这些常量前后均是两个下划线。

    2.获取类名、方法名、变量名的方法
    发现PHP强大之处之一,就是经常有意想不到函数或者是这些常量帮助你完成方便的完成某些功能。越来越体会到为什么PHP的比试题目里面会出现那么多考查具体的PHP函数的题目了。
    再一口气找了其他的一些常量或函数,持续添加。
    get_class(class name);        //取得当前语句所在类的类名
    get_class_methods(class name);    //取得class name 类的所有的方法名,并且组成一个数组
    get_class_vars(class name);    //取得class name 类的所有的变亮名,并组成一个数组

  • 【php】php Fatal error: Cannot redeclare class

    2010-11-28 15:45:35

    通常是文件重复包含问题引起的,比如应该使用include_once来包含文件,而不要只使用include包含,就可以避免了
  • .rpmnew和.rpmsave的问题

    2010-11-26 11:35:46

    原文转自:http://tech.idv2.com/2007/10/16/rpm-config-noreplace/

    RPM spec文件有个名为 %config 的宏,它可以标识配置文件,这样在升级时用户对配置文件做过的修改就不会丢失。没有它,用户千辛万苦修改过的配置文件会在升级过程中被覆盖。

    %config也可以写成%config(noreplace),不过网上关于它的说明却屈指可数。下面是关于这两者的一些实验,都是在RedHat 9的RPM(rpm-4.2-0.69)上进行的,其他版本有可能不同。

    RPM中的文件的制约条件有三个:1. 该文件在spec中如何标识(默认,%config或者%config(noreplace)); 2. 在rpm升级包中该文件是否被更新;3. 该文件是否被用户编辑过。

    下表就是各个条件的组合结果。

     文件标识 在RPM升级包中是否更新了?  旧版本文件未被用户编辑过   旧版本文件被用户编辑过
     默认  No  用新文件覆盖  用新文件覆盖
       Yes  用新文件覆盖  用新文件覆盖
     %config  No  用新文件覆盖  保持旧文件
       Yes  用新文件覆盖  旧文件改名为.rpmsave并复制新文件
     %config(noreplace)  No  用新文件覆盖  保持旧文件
       Yes  用新文件覆盖  保持旧文件,新文件安装为.rpmnew

     

    其中(noreplace)有效的两种情况上存在以下的问题:当spec文件中的定义改变时会发生什么?结论如下:

     文件标识 在RPM包中是否更新了?   旧版本文件被用户编辑过?
     由%config(noreplace)修改为%config  yes  旧文件改名为.rpmsave并安装新文件
     由%config修改为%config(noreplace)  yes  保持旧文件,新文件安装为.rpmnew

    结论:非配置文件或是上次安装后没有被修改的文件会被RPM包内的新文件覆盖。如果配置文件被修改过,但在新的RPM包中未作更新,则修改过的文件保留。仅当配置文件被修改并且在新的RPM包中被更新时,具体动作取决于(noreplace)。 %config使得旧文件被改名为.rpmsave并安装新文件,而%config(noreplace)将保持旧文件并将新文件安装为.rpmnew。

    建议一般配置文件都标识为(noreplace),除非升级所带来的配置文件变动非常重要,使用上一版本的配置文件无法正常工作时才使用%config。

  • 【php】数组下标不加引号报Notice: Use of undefined constant

    2010-11-19 19:57:27

    php数组中,数组下标不加引号,就会报错:Notice: Use of undefined constant
    如:$config[title]="FinalFantasy";
    Notice: Use of undefined constant title

    解决:title是个索引.是一定要加单引号的..
    否则php会先去查找是否存在title这个常量.
    然后再当索引处理.效率相差是很大的.

  • 【php】php中与数组相关的处理函数

    2010-11-18 21:01:08

    php数组的相关处理函数
    current(数组名称) 输出数组中一个字符串的值,从第一个起.
    key(数组名称) 输出数组中一个下标,从第一个起.
    next(数组名称) 控制数组指针向后移动.
    prev(数组名称) 控制数组指针向前移动.
    end(数组名称) 控制数组指针移向最后一位.
    reset(数组名称) 控制数组指针移向第一位.
    array_change_key_case(1.目标数组 2.CASE_UPPER大写 或 CASE_LOWER小写) 将数组下标全部改为大写或小写.
    array_chunk(1.目标数组 2.分解个数 3.输出布尔型的真或假) 将一个数组分解成多个小数组.
    array_count_values(数组名称) 用来计算数组中各值出现的次数.
    array_fill(1.下标从几开始 2.输出多少个 3.他们的值是什么) 用来做初始化数组.
    array_filter(1.目标数组 2.使用者定义的函数) 过滤函数,自定义以什么标准为真,以什么标准为假,此函数可以自动过滤掉假的字符串.
    array_flip(目标数组) 将下标变值,值变下标.
    array_sum(目标数组) 计算目标数组中所有元素值的总和.
    array_unique(目标数组) 去除目标数组中重复的值.
    array_values(目标数组) 将目标数组中所有下标都去掉,重新从"0"开始计算此函数中值的下标.
    array_keys(目标数组) 输出目标数组中的所有下标.
    in_array(1.要找的东西 2.目标数组 3.是否严格按照数据类型查找,是就输true) 查找目标数组中有无查找的数据.
    array_search(1.要找的东西 2.目标数组 3.是否严格查找) 查找目标数组中有无查找的数据,有则输出此数据的下标.
    array_key_exists(1.要找的下标 2.目标数组) 查找目标数组中有无查找的下标,有则输出true,无则输出false.
    extract(目标数组) 将数组转换成变量.
    compact(要转换成数组的变量下标) 将多个变量转换成数组.
    数组与栈 (先进后出)
    array_push(1.目标数组 2.压入栈的值) 压入栈函数.
    array_pop(目标数组) 弹出栈函数.
    数组与队 (先进先出)
    array_unshift(1.目标数组 2.压入对的值) 压入对函数.
    array_shift(1目标数组) 弹出对函数.
    忽略键名的数组排序:
    sort(目标数组) 从小到大的排序.
    rsort(目标数组) 从大到小的排序.
    保留键名的数组排序:
    asort(目标数组) 保留原下标,值从小到大的排序.
    arsort(目标数组) 保留原下标,值从大到小的排序.
    自然排序法排序:
    natsort(目标数组) 保留原下标,值从大到小的排序,不区分大小写.
    natcasesort(目标数组) 保留原下标,值从小到大的排序,不区分大小写.
    array_merge(1.目标数组 2.目标数组......) 合并多个数组.
    array_diff(1.被比数组 2.比数组 3.比数组......) 求数组的差积.
    array_intersect(1.被比数组 2.比数组 3.比数组......) 求数组的交积
  • java中读取配置文件

    2009-07-15 16:24:23

    这两天把自己的测试用例重新修改了一番,把原来一些不太规范的用法、写法做了更新,今天先记录java中读取配置文件的应用。

    定义一个Config类,包含多个static final的成员变量(全局静态一次初始化后不可被修改的变量),这些变量包括测试数据所在路径,测试中用多次用到的一些常量。config类中还包含一个private static的getProperty方法,用以获取config.ini文件中的属性值,并赋给static final常量。

    下面是getProperty方法,用到了java.util.Properties类:

    private static String getProperty(String property){
      String ConfigFile = "config.ini";//该文件默认位于.project文件同级目录下

         Properties p = new Properties();
         try {
           p.load(new FileInputStream(ConfigFile));
         } catch (FileNotFoundException e) {
          e.printStackTrace();
         } catch (IOException e) {
           e.printStackTrace();
         }
         String value = p.getProperty(property);
         //System.out.println(value);
      return value;
      
     }

    下面是config.ini配置文件:

    /*Soap服务器地址*/
    host=http://192.9.200.59:8000
    /*登录用户名*/
    user=admin
    /*登录密码*/
    pwd=123456
    /*资源路径*/
    resource=d:\data\

    调用getProperty获取配置文件:

    String serverhost=getProperty("host")//获取到配置文件中host所对应的等号后面的值;

  • C++学习笔记2

    2009-05-21 11:58:00

    今天要讨论关于指针的问题。

    char globlestr1[]="abcde";

    char globlestr2[]="abcde";

    int mian()
    {
      char *p = new char[10];
      strcpy(p,"abcde");  
        //指针的赋值方式;除了初始化时可以使用char* p="abcde"外,
        //其他情况是不正确的。例如*p= "abcd"是不对的,不可能将一个
        //字符串付给*p,因为*p是char类型
      printf("%s %d\n",p,p);
        //结果是: abcde 以及 p中存放的地址(即abcde位置)
      printf("%c %d %c\n",*p,*p,*(p+1));
        //结果是: a  97(a的整数值) 以及 b
      char str[]="ABCDE";
      printf("%s %d",str,str);
        //结果是: ABCDE 存放ABCDE的地址

        //另外看一下这个列子:

      char* p1="abcde";

      char* p2="abcde";

      printf("%d %d",p1,p2)

        //p1,p2输出结果相同,是同一个地址;在这个列子里,在栈里为p1、

        //p2分配两块不同的内存,单都指向同一个地址abcde;

      printf("%d %d",globlestr1,p1,globlestr2);

        //输出结果不同,虽然都是在数据段分配,但不是同一块地址;在这个

        //列子里,在数据段里为globlestr1和globlestr2分配了两块不同

        //的内存,但是存放的内容是相同的。
    }

  • C++学习笔记1

    2009-05-18 21:34:02

    1.using namespace std;和#include <iostream>还是#include<iostream.h>的问题

    一般都知道,要使用cout等方法必须 std::cout或者在前面使用using namespace std;但前提是需要包含头文件#include<iostream>,而不是iostream.h(有些编译器已经不再支持C头文件了,比如vs2008)。

    使用#include < iostream >,得到的是置于名字空间std下的iostream库的元素;如果使用#include < iostream.h >,得到的是置于全局空间的同样的元素。在全局空间获取元素会导致名字冲突,而设计名字空间的初衷正是用来避免这种名字冲突的发生。


    2.boolalpha的用法:
    int main()
    {
     using namespace std;
     bool a=true;
     cout<<a<<endl; //输出1
     boolalpha(cout); 
     cout<<a<<endl; //输出true
     noboolalpha(cout);
     cout<<a<<endl; //输出1
     cout<<boolalpha<<a<<endl; //输出true
    }

    3.内存划分问题-代码段、数据段、堆、栈

    代码段,顾名思义,代码存放于代码段;

    数据段,用于存放全局变量,全局变量初始化后不能改变;

    堆,程序中new出来的空间存放于堆中;

    栈,存放程序中的局部变量(跳出该段程序后空间被释放);

    4.举例说明3中各类内存段

    int a = 0; //全局变量,存放于数据段

    char *p1; //全局变量,存放于数据段;

    int main()

    {

    int b;//局部变量,存放于栈;

    char s[] = "abc"; //局部变量,存放于栈;

    char *p2; //局部变量,存放于栈;

    char *p3 = "abcd"; //p3存放于栈,“abcd”存放于数据段;

    static int c = 0; //全局变量,数据段;

    p1 = (char *)malloc(10); //malloc得来10字节存放于堆;

    strcpy(p1, "abcd"); //"abcd"存放于数据段,编译器可能会将它与p3所指向的"abcd"优化成一个地方

    return 0;

    }

    有了上面的说明,下面这个问题就可以轻易解决了:

    以下三条输出语句分别输出什么?

    char str1[]       = "abc";
    char str2[]       = "abc";
    const char str3[] = "abc";
    const char str4[] = "abc";
    const char* str5  = "abc";
    const char* str6  = "abc";
    cout << boolalpha << ( str1==str2 ) << endl; //
    false
    cout << boolalpha << ( str3==str4 ) << endl; // false

    cout << boolalpha << ( str5==str6 ) << endl; //  true


     

Open Toolbar