`
svyee
  • 浏览: 23760 次
  • 性别: Icon_minigender_1
  • 来自: 福建
最近访客 更多访客>>
社区版块
存档分类
最新评论

Symbian 中的动态数组 CArrayX

阅读更多

Symbian OS 中的动态数组CArrayX的存储方式分为连续存储(Flat)和分段存储(Segmented buffer)两种。

对于Flat方式,多用于查找比较频繁的地方。对于Segmented方式,多用于存储空间大小经常发生变化的时候。

由于存在连续存储和分段存储两种不同形式的存储,CArray可根据存储形式和存储内容的不同分为4种。

(1)Fix类型,每个元素都拥有相同的长度。
(2)Var类型,各元素拥有不同的长度,每给对象都保存在各自的堆单元中,数组空间中保存着各个元素的指针。
(3)Pak类型,数组中每个元素都有可变的长度,类似于描述符对象,每个元素前面都有其自身的长度信息。
(4)Ptr类型,指针数组。

在选择存储形式时,要考虑如下问题:

(1)是否需要经常的重新分配
(2)数据元素插入和删除的频率
(3)访问数据成员的速度

 

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

 

名称 元素大小 缓冲器类型 用法
CArrayFixFlat 固定大小 平面 很少进行分配时,用于存储固定大小的T类和R类对象
CArrayVarFlat 可变大小 平面 很少进行分配时,用于存储可变大小的T类和R类对象
CArrayPtrFlat 指针 平面 很少进行分配时,用于对象指针
CArrayPakFlat 大小可变(压缩) 平面 很少进行分配时,用于在一个堆单元中存储可变大小的T类或R类对象
CArrayFixSeg 固定大小 片断 频繁进行分配时,用于存储固定大小的T类和R类对象
CArrayVarSeg 可变大小 片断 频繁进行分配时,用于存储可变大小的T类和R类对象
CArrayPtrSeg 指针 片断 频繁进行分配时,用于存储对象指针

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

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

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

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

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

 

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

 

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

 

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

 

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

 

名称 键类型 说明
CArrayFixFlat TKeyArrayFix  
CArrayVarFlat TKeyArrayVar  
CArrayPtrFlat TKeyArrayFix派生类 需要特殊实现
CArrayPkgFlat TKeyArrayVar  
CArrayFixSeg TKeyArrayFix  
CArrayVarSeg TKeyArrayVar  
CArrayPtrSeg TKeyArrayFix派生类 需要特殊实现

 

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

TKeyArrayFix(TInt anOffset, TKeyCmpText aType)

这两个参数是:

 

    TInt    anOffset —类中字段的偏移量

    TKeyCmpText    aType — 对应字段的类型

 

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

 

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

 

字段类型 键类型
数据 ECmpTInt8、ECmpTInt16、ECmpTInt32、ECmpTInt、ECmpTUint8、ECmpTUint16、ECmpTUint32、ECmpTUint、ECmpTInt64
文本 ECmpNormal、ECmpNormal8、ECmpNormal16、ECmpFolded、ECmpFolded8、ECmpFolded16、ECmpCollated、ECmpCollated8、ECmpCollated16、

 

class TStudent
{
public:
    TStudent(const TDesC& aSName,TUint aSNo,TReal aScore);
public:
    TUint iSNo;
    TReal iScore;
    TBuf<10> iSName;
};

TStudent::TStudent(const TDesC& aSName,TUint aSNo,TReal aScore)
{
    iSNo = aSNo;
    iScore = aScore;
    iSName = aSName;
}

void ManageStu()
{
    //使用CArrayFixFlat,很少进行分配时,用于存储固定大小的T类和R类对象
    
    CArrayFixFlat<TStudent>* StuArrayFlat;
    //这里也可以改成CArrayFixSeg<TStudent>* StuArraySeg;    

    StuArrayFlat = new(ELeave)CArrayFixFlat<TStudent>(5);

    CleanupStack::PushL(StuArrayFlat);

    //分配空间存储两个学生的信息
    _LIT(KSTUDENT1,"GuanYabei");
    _LIT(KSTUDENT2,"WuMingshi");
    _LIT(KRETURN,"\n");
    
    TBuf<10> StuName1 = KSTUDENT1;
    TBuf<10> StuName2 = KSTUDENT2;

    //初始化两个学生的信息(姓名,学号,分数)
    TStudent stu1(StuName1,1,100.0);
    TStudent stu2(StuName2,2,99.5);

    //添加到数组中,请注意,用到的是AppendL()方法,它是可能引起异常的
    StuArrayFlat->AppendL(stu1);
    StuArrayFlat->AppendL(stu2);

    // 显示所有的学生信息
    _LIT(KFORMAT2,"id is %d");
    _LIT(KFORMAT3,"score is %f");

    for(TInt i=0; i<StuArrayFlat->Count(); i++)
    {
        console->Printf(_L("name is "));
        console->Printf((*StuArrayFlat)[i].iSName);
        // 如果你觉得指针括号太多而不够美观,我们也可以使用另一种方法
        // 即,使用At()函数
        // 如:console->Printf(StuArrayFlat->At(i).iSName);
        console->Printf(KRETURN);
        console->Printf(KFORMAT2,(*StuArrayFlat)[i].iSNo);
        console->Printf(KRETURN);
        console->Printf(KFORMAT3,(*StuArrayFlat)[i].iScore);
        console->Printf(KRETURN);
    }
    console->Printf(_L("Press any key to continue\n"));
    console->Getch();

    //删除数组中的元素
    console->Printf(_L("Delete first Student\n"));
    StuArrayFlat->Delete(0);
    for(i=0; i<StuArrayFlat->Count(); i++)
    {
        console->Printf(_L("name is "));
        console->Printf((*StuArrayFlat)[i].iSName);
        console->Printf(KRETURN);
        console->Printf(KFORMAT2,(*StuArrayFlat)[i].iSNo);
        console->Printf(KRETURN);
        console->Printf(KFORMAT3,(*StuArrayFlat)[i].iScore);
        console->Printf(KRETURN);
    }
    console->Printf(_L("Press any key to continuce\n"));
    console->Getch();

    //修改第一个学生的姓名
    console->Printf(_L("Modify first student's name\n"));
    console->Printf(_L("first student old name is "));
    console->Printf((*StuArrayFlat)[0].iSName);
    console->Printf(KRETURN);

    (*StuArrayFlat)[0].iSName = _L("GuanYabei");

    console->Printf(_L("first student new name is "));
    console->Printf((*StuArrayFlat)[0].iSName);
    console->Printf(KRETURN);

    console->Printf(_L("Press any key to continue\n"));
    console->Getch();

    //以姓名方式查找
    console->Printf(_L("Find student by name\n"));

    //建立主键,对于不同类型的CArray有不同的主键类型
    //_FOFF(c,f)宏来取得类中字段的偏移量
    TKeyArrayFix nameKey(_FOFF(TStudent,iSName), ECmpNormal);

    TInt findPos;
    TStudent S(StuName1,0,0);
    console->Getch();
    if(StuArrayFlat->Find(S, nameKey, findPos) != KErrNotFound)
    {
        //查找对象是S,按ECmpNormal格式
        console->Printf(_L("findPos is %d "),findPos);
        console->Printf((*StuArrayFlat)[findPos].iSName);//直接引用findPos的值,有的书上写findPos-1,这是错误的!
    }
    console->Printf(KRETURN);

    console->Printf(_L("Press any key to continue\n"));
    console->Getch();

    //以成绩方式排序
    TKeyArrayFix scoreKey(_FOFF(TStudent,iScore), ECmpTInt32);
    User::LeaveIfError(StuArrayFlat->Sort(scoreKey));

    for(i=0;i<StuArrayFlat->Count();i++)
    {
        console->Printf(_L("name is "));
        console->Printf((*StuArrayFlat)[i].iSName);
        console->Printf(KRETURN);
        console->Printf(KFORMAT2,(*StuArrayFlat)[i].iSNo);
        console->Printf(KRETURN);
        console->Printf(KFORMAT3,(*StuArrayFlat)[i].iScore);
        console->Printf(KRETURN);
    }

    CleanupStack::PopAndDestroy();
} 
 
分享到:
评论

相关推荐

    Symbian动态数组与缓冲区

    在Symbian操作系统中,动态数组和缓冲区的管理是至关重要的,特别是在嵌入式开发领域,高效且安全的数据结构是程序性能的关键因素。这里主要介绍Symbian系统中的RArray、RPointerArray以及CArrayX系列类,它们都是...

    symbian 数组排序

    在Symbian操作系统中,数组排序是一个常见的编程任务,特别是在处理大量数据时,例如在数据库操作中。Symbian提供了一系列的工具和方法来帮助开发者有效地对数组进行排序。本篇将深入探讨Symbian中数组排序的相关...

    Symbian OS课件(5)

    《Symbian OS课件(5)》主要涵盖了Symbian OS系统中关于基本类、字符串和动态数组的深入理解。这些是Symbian OS编程基础的重要组成部分,对于理解和开发在该平台上运行的应用程序至关重要。 Symbian OS是一个高度...

    将指定的图像多文件生成CFbsBitmap数组 对象

    最后,你可以使用Symbian的动态数组类,如`CArrayFixFlat&lt;T&gt;`,来存储这些`CFbsBitmap`指针,形成一个数组。 6. **释放资源**:处理完所有图像后,记得释放不再使用的资源,包括关闭文件和释放`CFbsBitmap`对象。 ...

    Symbian OS 考试大纲.pdf

    这部分介绍了Symbian OS中动态数组的使用方法。 #### 目标: - **动态数组操作:** - 了解动态数组的创建与销毁过程。 - 学会如何在程序中高效地使用动态数组。 ### 九、活动对象 **概述:** 活动对象是...

    symbian中动态加载汉字

    接下来,我们将详细探讨如何在Symbian中动态加载汉字。 ### 动态加载汉字的技术背景 在Symbian中处理汉字主要依赖于两个库:`utf.h` 和 `charConv.h`。其中: - **utf.h**:提供了一套用于处理UTF-16编码字符串的...

    symbian开发

    综上所述,Symbian C++编程基础涵盖了编码规范、工程文件管理、类型系统、异常处理、内存管理、描述符、动态数组以及活动对象等多个方面。深入了解这些内容,对于开发高质量、高效率的Symbian应用程序至关重要。

    信必安公司培训课件symbian

    9. **Part06-DynamicArrays.ppt**:动态数组是Symbian中一种重要的数据结构,这部分可能探讨了如何有效地使用和管理动态数组,以及其与C++标准库中的数组和向量的区别。 10. **Part04-TwoPhase.ppt**:两阶段提交...

    Symbian C++开发课件

    Symbian os C++开发课件 第一章 概述.pps 第二章 Symbian概述.pps 第三章 使用SDK开发程序.pps 第四章 基本的类、字符串和动态数组.pps 第五章 内存分配及异常处理.pps 第六章 GUI应用程序框架....

    Symbian实践培训讲义

    此外,动态数组和活动对象的概念也是Symbian开发中的重要组成部分,前者简化了动态大小数组的处理,后者则支持异步操作和事件驱动编程。 GUI编程在Symbian OS中涉及对话框、视图和控件的使用。中文化处理则确保应用...

    北京邮电大学symbian课件

    6. 第四章 基本的类、字符串和动态数组.pps:讲解Symbian中的数据类型、类库,以及如何管理和操作字符串和动态数组。 7. 第十一章 网络与通信.pps:这部分可能涉及Symbian如何支持网络连接,如TCP/IP通信、HTTP协议...

    Symbian学习笔记.pdf

    - Symbian平台中数组的使用方法。 - 包括基本操作和高级用法。 #### 十一、使用ListBox - 在Symbian应用程序中使用ListBox控件。 - 包括绑定数据源、样式定制等。 #### 十二、初识SettingItemList - ...

    symbian 的列表开发

    由于Symbian设备的资源限制,尽量减少不必要的内存分配和拷贝,合理使用缓存,以及选择合适的数据结构(如动态数组或链表),都可以提高列表操作的效率。 总结来说,"symbian的列表开发"涉及到Symbian系统中列表类...

    Symbian+开发中的类

    继承自CBase的类还有MDesCArrayBase,它是动态数组的基础,常用于存储和管理字符串。 另一个重要的基础类是RBuffer,它用于处理内存缓冲区。在处理数据传输或内存操作时,RBuffer可以提供高效且灵活的方式。RBuffer...

    Symbian课件1-6一起压缩的

    首先,我们从"第四章+基本的类、字符串和动态数组.rar"开始,这是Symbian编程的基础。Symbian C++语言中,类的使用是核心部分,包括系统提供的基础类以及开发者自定义的类。字符串处理在任何编程环境中都至关重要,...

    Symbian动态更改菜单例子源代码

    下面我们将详细探讨如何在Symbian中动态地初始化和修改菜单。 首先,`DynInitMenuPaneL`是Symbian系统中的一个关键类,用于动态初始化菜单项。这个类允许我们在程序运行时根据需要添加、删除或修改菜单项,而不是在...

    Symbian程序动态加载TTF字体使用小结

    ### Symbian程序动态加载TTF字体的深入解析与实践 #### 一、Symbian字体类型概览 Symbian系统支持多种字体格式,包括GDR、BDF以及更为通用的TTF字体。其中,TrueType Font (TTF) 字体格式因苹果和微软的共同推广而...

    Symbian塞班操作系统

    ### Symbian塞班操作系统深度解析 #### Symbian简介:智能移动终端的先驱者 Symbian操作系统,源自英国宝意昂公司(Psion)的EPOC操作系统,其设计理念强调“使用电子产品如同品尝乳酪般简单”。EPOC的命名灵感...

Global site tag (gtag.js) - Google Analytics