用户自定义类型— 结构体,共用体,枚举——谭浩强cpp(new/delete vs malloc/free)

用户自定义类型(user-defined type,UDT)
  • 结构体(structure)类型:在一个组合项中包含若干个类型不同(当然也可以相同)的数据项。

    • 下面的定义相当于一个模型,其中并无具体数据,系统也不为之分配实际的内存单元。在编译时,是不会为类型分配空间的,只为变量分配空间。
    struct 结构体类型名
    {成员表列};
    
    struct student
    {
    	string name;
        int age;
        double score;
    
    };
    
    • 在声明一个结构体类型时必须对各成员都进行类型声明,即 类型名 成员名;
    • 每一个成员也称为结构体中的一个域(field)。成员表列又称为域表。成员名的定名规则与变量名的定名规则相同。
  • 定义结构体类型变量的方法

    • 先声明结构体类型再定义变量名。student stu1 = {...};
    • 在声明类型的同时定义变量。struct student{...}stu1{...},stu2{...};
    • 直接定义结构体类型变量. struct {...}stu1,stu2;//注意没有结构体类型名
  • 结构体变量的初始化

    • 定义时指定初始值。
    • 声明类型与定义变量分开,在定义变量时进行初始化.
  • 结构体变量的引用

    • 将一个结构体变量的值赋给另一个具有相同结构的结构体变量。stu1 = stu2;
    • 引用一个结构体变量中的一个成员的值。stu1.num.对变量的成员赋值:stu1.num = 10010;
    • 成员本身也是一个结构体类型,则要用若干个成员运算符,一级一级地找到最低一级的成员:student1.birthday.month;
    • 不能将一个结构体变量作为一个整体进行输入和输出。
    • 对结构体变量的成员可以像普通变量一样进行各种运算。
    • 可以引用结构体变量成员的地址,也可以引用结构体变量的地址。如 cout<<&stu1; cout<<&stu1.age;
  • **结构体数组:**每个数组元素都是一个结构体类型的数据,它们都分别包括各个成员项。stu1[10];

    • 初始化: student stu[ ]={{…},{…},{…}}; //已事先声明了结构体类型student。一个结构体常量应包括结构体中全部成员的值。
  • 指向结构体变量的指针

    • 可以设一个指针变量p,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。
    以下3种形式等价: 
    ①  结构体变量.成员名。如stu.num。
    ②  (*p).成员名。如 (*p).num。
    ③  p->成员名。如p->num。“->”称为指向运算符。
    
    • 指针变量也可以用来指向结构体数组中的元素。
  • 静态链表:对各结点既可以通过上一个结点的next指针去访问,也可以直接通过结构体变量名a,b,c去访问。

  • 动态链表:各结点是可以随时插入和删除的,这些结点并没有变量名,只能先找到上一个结点,才能根据它提供的下一结点的地址找到下一个结点。只有提供第一个结点的地址,即头指针head,才能访问整个链表。

    • 需要用到动态分配内存的运算符new和动态撤销内存的运算符delete
  • newdelete

    • C语言中是利用库函数mallocfree来分配和撤销内存空间的。
    • **newdelete**是运算符,不是函数,因此执行效率高。
    • new 类型 [初值](方括号是可选的意思)。用new分配数组空间时不能指定初值。如果由于内存不足等原因而无法正常分配空间,则new会返回一个空指针NULL用户可以根据该指针的值判断分配空间是否成功。

摘自:https://www.cnblogs.com/tp-16b/p/8684298.html (侵删)下面那张图片也是

  • malloc/free只是动态分配内存空间/释放空间。而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理成员)。
  • 它们都是动态管理内存的入口。
  • malloc/free是C/C++标准库的函数,new/delete是C++操作符。
  • malloc/free需要手动计算类型大小且返回值w为void*,new/delete可自动计算类型的大小,返回对应类型的指针。
  • malloc/free管理内存失败会返回0,new/delete等的方式管理内存失败会抛出异常。
  • 尽管看起来new、new[] 和malloc 都能开得空间出来,并且以new 、new[]的方式好像还更有优势。但从系统层面看来,真正开出空间来的还是malloc。为什么这么说呢?
  • Primer书中有提到说: new/delete的表达式与标准库函数同名了,所以系统并没有重载new或delete表达式。new/delete真正的实现其实是依赖下面这几个内存管理接口的。c++中称之为“placement版”内存管理接口

用户自定义类型— 结构体,共用体,枚举——谭浩强cpp(new/delete vs malloc/free)_第1张图片

  • 共用体(union)类型:使几个不同的变量共占同一段内存的结构。使用覆盖技术,几个变量互相覆盖。

    • 声明共用体类型和定义共用体变量一般形式与结构体类似。
    • 结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。
    • 共用体变量所占的内存长度等于最长的成员的长度
  • 使用共用体变量的目的是希望用同一个内存段存放几种不同类型的数据。但请注意: 在每一瞬时只能存放其中一种,而不是同时存放几种。

  • 能够访问的是共用体变量中最后一次被赋值的成员,在对一个新的成员赋值后原有的成员就失去作用。

  • 共用体变量的地址和它的各成员的地址都是同一地址。

  • 不能对共用体变量名赋值;不能企图引用变量名来得到一个值;不能在定义共用体变量时对它初始化;不能用共用体变量名作为函数参数

  • 枚举(enumeration)类型 —— enum 枚举类型名{枚举常量列表};

    • 将变量的值一一列举出来,变量的值只能在列举出来的值的范围内。
    • enum weekday{sun,mon,tue,wed,thu,fri,sat};。这声明了一个枚举类型weekday,花括号中sun,mon,…,sat等称为枚举元素或枚举常量。表示这个类型的变量的值只能是以上7个值之一。
    • 定义变量weekday workday,week_end;,C语言中在最前面加enum。根据上面对weekday的定义,枚举变量的值只能是sunsat之一。
    (1) 对枚举元素按常量处理,故称枚举常量。
    (2) 枚举元素作为常量,它们是有值的,C++编译**按定义时的顺序对它们赋值为0,1,2,3,…**。也可以在声明枚举类型时另行指定枚举元素的值。
    (3) 枚举值可以用来做判断比较。
    (4) 一个整数不能直接赋给一个枚举变量。
    
  • typedef:声明一个新的类型名来代替已有的类型名。

    • 声明一个新的类型名的方法是:
      ① 先按定义变量的方法写出定义语句(如int i;: int n[100];)。
      ② 将变量名换成新类型名(如将i换成COUNT,将n换成NUM)。
      ③ 在最前面加typedef(如typedef int COUNTtypedef int NUM[100])。
      ④ 然后可以用新类型名去定义变量。(如: NUM n;(n是包含100个整型元素的数组))
  • 习惯上常把用typedef声明的类型名用大写字母表示,以便与系统提供的标准类型标识符相区别。

  • typedef可以声明各种类型名,但不能用来定义变量。

  • typedef只是对已经存在的类型增加一个类型名,而没有创造新的类型。

  • 使用typedef有利于程序的通用与移植。有时程序会依赖于硬件特性,用typedef便于移植。

下一篇开始写类(class)类型。

你可能感兴趣的:(编程语言,cpp语法)