• Symbian 中的动态数组 CArrayX(转)


    关键字: symbian c++ 动态数组

    Symbian OS 中的动态数组CArrayX的存储方式分为连续存储(Flat)和分段存储(Segmented buffer)两种。
    对于Flat方式,多用于查找比较频繁的地方。对于Segmented方式,多用于存储空间大小经常发生变化的时候。
    由于存在连续存储和分段存储两种不同形式的存储,CArray可根据存储形式和存储内容的不同分为4种。
    (1)Fix类型,每个元素都拥有相同的长度。
    (2)Var类型,各元素拥有不同的长度,每给对象都保存在各自的堆单元中,数组空间中保存着各个元素的指针。
    (3)Pak类型,数组中每个元素都有可变的长度,类似于描述符对象,每个元素前面都有其自身的长度信息。
    (4)Ptr类型,指针数组。
    在选择存储形式时,要考虑如下问题:
    (1)是否需要经常的重新分配
    (2)数据元素插入和删除的频率
    (3)访问数据成员的速度

    下表中列出了可以使用的CArray类型:

    image

    从上表中,我们知道了CArray提供了多个版本的类用来提供给用户更多的选择。通常我们常用的有4种:

    CArrayVarFlat:存储可变长度元素,存储方式为Flat。

    CArrayVarSeg:存储可变长度元素,存储方式为Segment。

    CArrayPakFlat:存储固定的或者可变长度的元素,而且每个元素都保留自己的长度信息。

    CArrayPtrFlat:存储数组指针,存储方式为Segment。

    ◎ 下面,我们将使用CArrayFixFlat和CArrayFixSeg来写一个例子,实际上,在下面的那个例子里,两个数组是完全可以互换的,因此,我只需要写一个就足够了。

    在给出例子之前,我们还要再讲一下CArray的排序与查找,由于CArrayX不同于RArray类,因此,在查找与排序方面也是有很大区别的。

    对于排序,我们首先要构造一个适当的键,这个键将是你排序的根本,在声明键时要指明排序的类型、字段偏移量和文本长度。其次,将键传入Sort()方法中进行排序。

    下表为CArray类不同类型时,所要用到的键类型:

    image

    由于下面的例子中,我们使用了CArrayFixFlat,因此我们的键就是TKeyArrayFix(依照上表)

    Cpp代码

    1. TKeyArrayFix(TInt anOffset, TKeyCmpText aType) 
    TKeyArrayFix(TInt anOffset, TKeyCmpText aType)

    这两个参数是:

        TInt    anOffset —类中字段的偏移量

        TKeyCmpText    aType — 对应字段的类型

    对于第一个参数,Symbian中提供了一个_FOFF(c,f)宏来取得类中字段的偏移量,其中,c为类命,f为字段命。如:_FOFF(TStudent,iSName);

    对于第二个参数,我们通常是可以有据可循的,请见下表:

    image

    Cpp代码

    1. class TStudent 
    2. public: 
    3.     TStudent(const TDesC& aSName,TUint aSNo,TReal aScore); 
    4. public: 
    5.     TUint iSNo; 
    6.     TReal iScore; 
    7.     TBuf<10> iSName; 
    8. }; 
    9. TStudent::TStudent(const TDesC& aSName,TUint aSNo,TReal aScore) 
    10.     iSNo = aSNo; 
    11.     iScore = aScore; 
    12.     iSName = aSName; 
    13. void ManageStu() 
    14. //使用CArrayFixFlat,很少进行分配时,用于存储固定大小的T类和R类对象
    15.     CArrayFixFlat<TStudent>* StuArrayFlat; 
    16. //这里也可以改成CArrayFixSeg<TStudent>* StuArraySeg;   
    17.     StuArrayFlat = new(ELeave)CArrayFixFlat<TStudent>(5); 
    18.     CleanupStack::PushL(StuArrayFlat); 
    19. //分配空间存储两个学生的信息
    20.     _LIT(KSTUDENT1,"GuanYabei"); 
    21.     _LIT(KSTUDENT2,"WuMingshi"); 
    22.     _LIT(KRETURN,"\n"); 
    23.     TBuf<10> StuName1 = KSTUDENT1; 
    24.     TBuf<10> StuName2 = KSTUDENT2; 
    25. //初始化两个学生的信息(姓名,学号,分数)
    26.     TStudent stu1(StuName1,1,100.0); 
    27.     TStudent stu2(StuName2,2,99.5); 
    28. //添加到数组中,请注意,用到的是AppendL()方法,它是可能引起异常的
    29.     StuArrayFlat->AppendL(stu1); 
    30.     StuArrayFlat->AppendL(stu2); 
    31. // 显示所有的学生信息
    32.     _LIT(KFORMAT2,"id is %d"); 
    33.     _LIT(KFORMAT3,"score is %f"); 
    34. for(TInt i=0; i<StuArrayFlat->Count(); i++) 
    35.     { 
    36.         console->Printf(_L("name is ")); 
    37.         console->Printf((*StuArrayFlat)[i].iSName); 
    38. // 如果你觉得指针括号太多而不够美观,我们也可以使用另一种方法
    39. // 即,使用At()函数
    40. // 如:console->Printf(StuArrayFlat->At(i).iSName);
    41.         console->Printf(KRETURN); 
    42.         console->Printf(KFORMAT2,(*StuArrayFlat)[i].iSNo); 
    43.         console->Printf(KRETURN); 
    44.         console->Printf(KFORMAT3,(*StuArrayFlat)[i].iScore); 
    45.         console->Printf(KRETURN); 
    46.     } 
    47.     console->Printf(_L("Press any key to continue\n")); 
    48.     console->Getch(); 
    49. //删除数组中的元素
    50.     console->Printf(_L("Delete first Student\n")); 
    51.     StuArrayFlat->Delete(0); 
    52. for(i=0; i<StuArrayFlat->Count(); i++) 
    53.     { 
    54.         console->Printf(_L("name is ")); 
    55.         console->Printf((*StuArrayFlat)[i].iSName); 
    56.         console->Printf(KRETURN); 
    57.         console->Printf(KFORMAT2,(*StuArrayFlat)[i].iSNo); 
    58.         console->Printf(KRETURN); 
    59.         console->Printf(KFORMAT3,(*StuArrayFlat)[i].iScore); 
    60.         console->Printf(KRETURN); 
    61.     } 
    62.     console->Printf(_L("Press any key to continuce\n")); 
    63.     console->Getch(); 
    64. //修改第一个学生的姓名
    65.     console->Printf(_L("Modify first student's name\n")); 
    66.     console->Printf(_L("first student old name is ")); 
    67.     console->Printf((*StuArrayFlat)[0].iSName); 
    68.     console->Printf(KRETURN); 
    69.     (*StuArrayFlat)[0].iSName = _L("GuanYabei"); 
    70.     console->Printf(_L("first student new name is ")); 
    71.     console->Printf((*StuArrayFlat)[0].iSName); 
    72.     console->Printf(KRETURN); 
    73.     console->Printf(_L("Press any key to continue\n")); 
    74.     console->Getch(); 
    75. //以姓名方式查找
    76.     console->Printf(_L("Find student by name\n")); 
    77. //建立主键,对于不同类型的CArray有不同的主键类型
    78. //_FOFF(c,f)宏来取得类中字段的偏移量
    79.     TKeyArrayFix nameKey(_FOFF(TStudent,iSName), ECmpNormal); 
    80.     TInt findPos; 
    81.     TStudent S(StuName1,0,0); 
    82.     console->Getch(); 
    83. if(StuArrayFlat->Find(S, nameKey, findPos) != KErrNotFound) 
    84.     { 
    85. //查找对象是S,按ECmpNormal格式
    86.         console->Printf(_L("findPos is %d "),findPos); 
    87.         console->Printf((*StuArrayFlat)[findPos].iSName);//直接引用findPos的值,有的书上写findPos-1,这是错误的!
    88.     } 
    89.     console->Printf(KRETURN); 
    90.     console->Printf(_L("Press any key to continue\n")); 
    91.     console->Getch(); 
    92. //以成绩方式排序
    93.     TKeyArrayFix scoreKey(_FOFF(TStudent,iScore), ECmpTInt32); 
    94.     User::LeaveIfError(StuArrayFlat->Sort(scoreKey)); 
    95. for(i=0;i<StuArrayFlat->Count();i++) 
    96.     { 
    97.         console->Printf(_L("name is ")); 
    98.         console->Printf((*StuArrayFlat)[i].iSName); 
    99.         console->Printf(KRETURN); 
    100.         console->Printf(KFORMAT2,(*StuArrayFlat)[i].iSNo); 
    101.         console->Printf(KRETURN); 
    102.         console->Printf(KFORMAT3,(*StuArrayFlat)[i].iScore); 
    103.         console->Printf(KRETURN); 
    104.     } 
    105.     CleanupStack::PopAndDestroy(); 
    106. }  
  • 相关阅读:
    【Java并发】并发笔记(一)
    【深入Java基础】排序算法(一)
    QDU-GZS and String
    牛客网36-A,B题解
    QDU-GZS与素数大法(素数筛法)
    csdn自动展开+去广告+净化剪切板+免登陆(如有侵权,立即删博)
    QDU第一届程序设计大赛——E到I题解法(非官方题解)
    Codeforces Round #529 -C- Powers Of Two(二进制拆分)
    CodeForces
    分配物资(模拟)
  • 原文地址:https://www.cnblogs.com/yaoliang11/p/1793711.html
Copyright © 2020-2023  润新知