zoukankan      html  css  js  c++  java
  • C++/C学习笔记(七)

                               C++/C学习笔记(七)

    1.联合(union

    联合也是一种构造数据类型,它提供了一种使不同成员之间共享存储空间的方法,同时可以实现不同类型数据成员之间的自动类型转换。但与结构不同的是,联合对象在同一时间只能存储一个成员的值(即只有一个数据是活跃的)。

    联合的内存大小取决于其中字节数最多的成员,而不是累加,联合也会进行字长对齐,与位域不同的是,使用联合不会带来任何额外的运行时开销。联合中存储的数据的值完全取决于对它的解释方式。在定义联合变量时可以指定初始值,但是只能指定一个初始值,而且该初始值的类型必须与联合的第一个成员的类型匹配。可以取一个联合变量的地址,等同于其任一成员的地址。

    可以在同类型的联合变量之间赋值,但是不能比较两个联合变量的大小,不只是因为可能存在填补字节,而且这两个变量可能存储着不同类型的成员,因此它们实际上代表两个类型不同的变量。

    C++Cunion进行了扩展,除了数据成员外还可以定义成员的访问说明符,可以定义成员函数,构造函数和析构函数。但是联合不能包含虚拟成员函数和静态数据成员,不能作为其他类型的基类或者派生自其他类型。C++还支持匿名联合。

    比如定义一个用于社会中的“人”的类型,并且假设不会同时使用身份证号码和姓名,就可以定义如下:

    #include<cassert>

    #include<iostream>

    #include<iomanip>

    using namespace std;

    class Person{

    public:

    Person():type(true){id.ID=0;}

    void SetID(unsigned long double newId){

    id.ID=newId;

    type=true;

    }

    unsigned long double GetID()const{

    assert(type!=false);

    return id.ID;

    }

    void SetName(const char* name){

    strcpy(id.name,name);

    type=false;

    }

    const char* GetName() const {

    assert(type!=false);

    return id.name;

    }

    bool IDIsSelected() const {return type;}

    bool NameIsSelected()const {return (!Type);}

    private:

    union Choice

    {

    unsigned long ID; //身份证号码

    char name[20]; //姓名

    };

    Choice id; //ID/name

    bool type; //标识当前存放的是ID(true)还是name(false)

    };

    int main(int argc,char* argv[])

    {

    Person p1;

    p1.SetID(123456);

    cout<<p1.GetID()<<endl;

    p1.SetName("HYQ");

    cout<<p1.GetName()<<endl;

    if(p1.NameIsSelected())

    cout<<"Now,id is type of name."<<endl;

    else

    cout<<"Now,id is type of ID."<<endl;

    return 0;

    }

    输出:

    123456

    HYQ

    Now,id is type of name.

    联合的另一个妙用就是用来解析一个寄存器或多字节内存变量的高低字节的值,而不用我们手工使用位运算符来解析它们。

     

    2.枚举(Enum

    C++/C枚举类型允许我们定义特殊用途的一组符号常量,它表明这种类型的变量可以取值的范围。当定义一个枚举类型的时候,如果不特别指定其中标识符的值,则第一个标识符的值将为0,后面的标识符比前面的标识符依次大1;若指定了其中某一个标识符的值,那么它后面的标识符自动在前面的标识符值的基础上依次加1,除非同时还指定了它们的值。例如:

    enum Week {Sun, Mon=125, Tue, Wed, Thu=140, Fri, Sat};

    则枚举类型Week中各符号常量的值依次为0125126127140141142

    枚举变量和常量都可以参与整型变量能够参与的某些运算,但不能用枚举变量赋予一个不在枚举常量列表中的值,不要使用++--+=-=等操作,除非你特别为它重载了这些运算符。

    枚举类型变量一般可以直接转换成某种整数类型,除非其值超出了这种整数类型可以表示的范围。但是一个整型变量在强制转换成枚举类型后就不一定具有一个有效的值了,因为整型数是连续的,而枚举变量的取值很可能是不连续的。

    枚举类型还可以是匿名的,匿名的枚举类型就相当于直接定义的const符号常量,可以作为全局枚举,也可以放在任何类定义或名字空间中。

     

    3.文件

    文件操作属于一种I/O操作,通过标准的I/O函数库来实现。

    任何对象和文件只有与具体的应用相关联才有含义,否则就是一些单纯的字节序列。也就是说,并不存在一种固定的“文件记录”,任何有意义的文件格式都是由具体的应用领域决定的。

    C++/C中,文件操作是通过和“流”这种对象关联而进行的,流即为字节流。当打开一个文件的时候,操作系统就建立一个流对象并与该文件关联。操作系统维护了一个保存当前系统中所有打开文件的文件控制块(FCB)的数组,并利用每一个FCB来管理对每一个文件的操作,数组的上限就是操作系统允许你同时打开的文件个数的上限。

    C语言中,首先声明一个FILE结构的指针,然后调用库函数fopen()fopen()动态创建一个FILE结构对象并分配一个文件句柄,从磁盘文件中读入FCB结构并填入FCB数组中,然后返回这个FILE结构的地址。此后就可以拿着这个地址调用文件操作库函数来完成特定的任务。最后调用fclose()函数销毁动态创建的FILE结构对象,同时释放文件句柄并刷新缓冲区。

    C++实现了面向对象的I/O系统,不再让用户直接使用“文件指针”这种原始的设施,而是把任何文件看做一个对象,对该对象的操作就是在对一个文件进行操作,同时允许用户为自定义数据类型定制I/O操作。

  • 相关阅读:
    [ACM_数学] 大菲波数 (hdu oj 1715 ,java 大数)
    [ACM_水题] 不要62(hdu oj 2089, 不含62和4的数字统计)
    [ACM_其他] Square Ice (poj1099 规律)
    [ACM_图论] Domino Effect (POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板)
    [ACM_搜索] Triangles(POJ1471,简单搜索,注意细节)
    [ACM_图论] Sorting Slides(挑选幻灯片,二分匹配,中等)
    [ACM_图论] The Perfect Stall 完美的牛栏(匈牙利算法、最大二分匹配)
    [ACM_几何] Metal Cutting(POJ1514)半平面割与全排暴力切割方案
    [ACM_动态规划] 轮廓线动态规划——铺放骨牌(状态压缩1)
    [ACM_数据结构] 竞赛排名
  • 原文地址:https://www.cnblogs.com/yingying0907/p/2628692.html
Copyright © 2011-2022 走看看