指针|【发际线大作战】C++学习记录之用户自定义数据类型

好久没有开头的骚话环节了
指针|【发际线大作战】C++学习记录之用户自定义数据类型
文章图片

因为最近的ddl实在是太多了
菌er表示有被ze磨到
可能是我站的不够高吧==
1.结构体类型 【指针|【发际线大作战】C++学习记录之用户自定义数据类型】将不同类型的数据组合成为一个有机整体。eg:一个学生的学号、姓名、性别、成绩等,都是这个学生的属性。
声明结构体类型的一般形式:
struct 结构体类型名{成员表列}; //一定要加分号
结构体类型名用来作结构体类型的标志:
大括号内是结构体中的全部成员;
在声明一个结构体类型时必须对各成员都进行类型声明;
每一个成员也成为结构体中的一个域,成员表列又称为域表。
定义的方法以及初始化 方法

  • (1)先声明结构体,再定义变量名。
  • (2)在声明类型的同时定义变量(在分号前面,括号的后面)即: struct student { 成员表列} 变量名列表;
  • (3)直接定义结构体类型变量 即:struct { 成员表列 } 变量名表列;//将所有实体声明出来 后期不再添加 所以用的比较少
tips:
  • 类型和变量的概念不同,编译时,不为类型分配空间,只为变量分配空间。
  • 对结构体中的成员(即“域”),可以单独使用。
  • 成员也是一个结构体变量,可对其进行赋值。 格式为 结构体类型名 . 成员名 = a ;
  • 结构体中的成员名可与程序中的变量名相同,但两者没有关系。
初始化
指针|【发际线大作战】C++学习记录之用户自定义数据类型
文章图片

引用结构体变量
  • (1)将一个结构体的值赋给另一个具有相同结构的结构体变量
  • (2)引用一个结构体变量中的一个成员的值
  • (3)if (成员是结构体类型) 用若干的成员运算符 找到最低一级的成员。 eg: student.birthday. month=12;
  • (4)不能将结构体作为一个整体输入输出。只能对结构体变量中的各个成员分别进行输入输出。
  • (5) 成员之间可根据类型进行各种运算。“ . ”的运算符的优先级最高,eg:student1.age++ == (student.age)++
  • (6)可以引用结构体变量成员地址,也可以引用结构体变量的地址。地址主要用作函数参数,将结构体变量的地址传递给形参。
    eg:
cout<<&student1; //输出student1的首地址 cout<<&student1.agel//输出student1.age的地址

结构体数组 定义
  • (1)方法一
    eg:
struct stud{成员列表}; student std[10]; for(int i=0; i<10; i++)//用循环语句处理赋值问题 { cin>>s[i].nn>>endl; //赋值 }

  • (2)方法二
    eg:
    struct student {成员表列}stu[3]={{声明内容},{声明内容}};
    或 struct {成员表列 }stu[3]={{声明内容},{声明内容}};
指向结构体变量的指针 定义方法
  • 结构体变量.成员名
  • (*p).成员名
  • p->成员名
    eg:
struct student{成员表列}; student stu; //定义student类型的变量stu student *p=&stu; //定义p指向student类型数据的指针变量并指向stu stu.num=10310; //直接赋值 //等价于 p->num=10310; //等价于 (*p).num=10310; cout<<(*p).name<
p->n++ p指向结构体变量中的成员,用完该值后再使它加1。
++p->n p指向结构体变量中的成员,并使之加1,然后再使用。
链表
由结构体变量和指向结构体变量的指针构成(利用零散的空间)
链表有一个“头指针”变量head 用 *h表示
链表中每一个元素称为“结点”
结点的前一个结点称为前趋
表尾存上只下一个结点的地址为单向链表,存上上一个和下一个结点的地址为双向链表。
存放的数据组成的空间称为数据域,存放地址的空间称为指针域。
结构体类型数据作为函数参数
  • 用结构体变量作为数组名 传递参数(占内存大 pass) eg:void print(Node std) {内容} int main(){print(student); }
  • 用指针作为实参(效率比高 但不直接) eg:void print(Node *p) {内容} int main(){ student *p=&stu; print(pt); }
  • 将结构体变量的地址作为函数参数 (效率高 内存小)
    eg:
struct student{内容}; void main() { void print(student &); print(stu); } void print(student &stud) //形参为结构体student变量的引用 {内容}

例题——候选人得票统计(无注释 因为懒【误)
void Ln() { cout<n; Ln(); for(i=1; i<=n; i++) { cout<<"请第"<

new运算符 定义动态空间
格式 new 类型[n] //声明过程其实就是三连问 你要开辟动态空间吗?Yes,写个new 你要声明啥类型呀?emmm 整型吧 你要开辟多大的空间呀?2333 你笑啥呀==?(超过了三个问题啊喂!
为了避免声明过后找不着了,所以动态空间必须用一个指针保存下来 eg:int *p; p=new int[6]; //利用new运算符声明数组
Tips:
  • 用new开辟的新内存单元无名字,指向其首地址是引用的唯一途径。
  • 不能在分配空间时初始化。
  • 空间一般不主动收回,需要用delete运算符收回。
    eg:
int *point; new int[5]; delete [5]point; //如果开辟的是 //new int; //收回是 //delete point;

内存中没有enough space new 运算符返回空指针NULL(0)
2.共同体类型(联合体类型) 如果要把整型、字符型、双精度浮点型变量放在同一个地址开始的内存单元中,由于三种变量的字节数不同,但都是在同一个地址开始存放。也就是使用覆盖技术,几个变量相互覆盖。
共同体类型 使几个不同的变量共占同一段内存的结构。(简单来说,给union类型的变量分配的空间大小为字节数最大的成员变量的大小 eg:成员表列有 int i; char ch; double d; 分配的空间为double类型的字节数 也就是8)
格式 union{成员表列};
共同体的属性和结构体相似。
区别是
  • 分配空间的方式不同
  • 共同体赋值方式为先来后到,即使用时覆盖上次的赋值
3.枚举类型 枚举类型 有几种可能的值的变量
**格式 enum 变量名{可能值} **
eg:enum weekday{sun,mon,tue,wed,thu,fri,sat};
声明过后即可用它来定义变量。(也可以直接定义 eg:enum weekday{sun,mon,tue,wed,thu,fri,sat},week_end; workday=mon;
eg:weekday workday,week_end; workday=mon; week_end=sat; //workday和week_end的取值只有以上七种
Tips:
  • 枚举元素按常量处理,所以又称为枚举常量
  • 按照定义的顺序编号,可以按照序号来赋值
4.用typedef声明新的类型名 格式 typedef 旧的类型 新的类型;
eg: typedef float REAL; //指定用REAL代替 float
只能代替已有的类型。
常把用typedef声明的类型名用大写字母表示。
应用
  • typedef struct {成员表列} 新类型;
    eg: typedef struct {成员表列} DATE; //DATE是新类型名,而不是结构体变量名,DATE代替struct。
  • typedef int NUM[100]; //声明NUM为整型数组
    NUM n; //定义n为包含100个整型元素的数组
  • typedef char *STRING; //声明STRING为字符指针类型
    STRING p,s[10]; //p为字符指针变量,s为指针数组(有10个元素)
  • typedef int (*P)() //声明p为指向函数的指针类型,函数返回整型值P
    p1,p2; //p1,p2为P类型的指针变量

    推荐阅读