《C++》基础入门_10——用户自定义数据类型详细篇

以下内容为大学期间学习C++语言总结的知识:

《C++》基础入门_01——数据存储,表示形式,基本运算
《C++》基础入门_02——面向对象的总体概括
《C++》基础入门_03——程序的开发过程
《C++》基础入门_04——四大语句
《C++》基础入门_05——函数详解篇
《C++》基础入门_06——面向对象的详述
《C++》基础入门_07——数据的共享保护:const
《C++》基础入门_08——利用数组实现对批量数据的处理
《C++》基础入门_09——指针和引用的讲解
《C++》基础入门_10——用户自定义数据类型详细篇
《C++》基础入门_11——友元的讲解
《C++》基础入门_12——类模板
《C++》基础入门_13——运算符的重载
《C++》基础入门_14——继承与派生
《C++》基础入门_15——多态性
《C++》基础入门_16——输入输出流详讲
《C++》基础入门_17——对象串行化
《C++》基础入门_18——异常处理
《C++》基础入门_19——命名空间
《C++》基础入门_20——文件操作
《C++》基础入门_21——在函数中返回数组的常用方法



一、结构体类型

在一个组合中包含若干个类型不同的数据项。相当于其他高级语言中的记录。

1.1 声明

  • 一般形式:

    struct 结构名{
      数据类型 成员名 1;
      数据类型 成员名 2;
          :
      数据类型 成员名 n;
    };
    
    1. 结构体类型名作为结构体类型的标志。
    2. 声明一个结构体类型时必须对各个成员进行类型声明:类型名 成员名;
    3. 每一个成员也成为结构体中一个域,所以成员表又称为域表。
    4. 结构体的成员可以是数据,又可以是函数。
  • 声明结构体并不实际分配内存单元。

    struct Student  //声明一个结构体类型
    {
    	int num;
    	char name[20];
    	char sex;
    	int age;
    };
    
  • 注意:

    1. 结构变量的存储类型概念、它的寿命、可见性及使用范围与普通变量完全一致。
    2. 结构变量说明在结构类型声明之后,二者也可同时进行。
    3. 结构变量占内存大小可用 sizeof 运算求出: sizeof(运算量)

1.2 结构体类型变量的定义方法与初始化

  • 定义结构体类型变量的2中方法:
    1. 先声明结构体类型再定义变量

      Student student1,student2;//student1,student2是两个结构体类型Student的变量
      
    2. 声明结构体类型的同时定义变量
      一般形式:

      struct   结构体类型名{
             成员名;
      } 变量名表;
      

      例如:

      struct Student
      {
      	int num;
      	char name[20];
      	char sex;
      	int age;
      }student1,student2;//student1,student2是两个结构体类型Student的变量
      
    当多文件引用同一个结构体变量时,采用第一种方法;否则可采用第二种。
    定义了结构体变量之后,系统会给它分配内存空间。
  • 初始化
    1. 可以在声明结构体并定义变量时初始化

             struct Student
      		{
      			int num;
      			char name[20];
      			char sex;
      			int age;
      		}student1={201313232,“yejing”,‘f’,18}
    2. 结构体声明与定义分开的情况,在定义变量时初始化。

      
          Student student1={201313232,“yejing”,‘f’,18}

1.3 引用结构体变量

  1. 可以将一个结构体变量的值赋给另一个具有相同结构的结构体变量。

    student1=student2;

  2. 可以引用一个结构体变量中的一个成员的值。
    引用形式:
    结构体变量名.成员名
    " . " : 成员运算符

    student1.name;

#include <iostream>
using namespace std;
struct Student
{
	int num;
	char name[20];
	char sex;
	int age;
}student1,student2;
int main() {
	student1 = { 123,"yejing",'f',18 };
	student2 = student1; 
	cout << student1.num << "  " << student2.num;  //  123     123
	cout << student1.name << "  " << student2.name; // yejing  yejing
}

1.4 结构体数组

每个数组元素都是一个结构体类型的数据,它们分别都包含各自的成员项。

#include <iostream>
using namespace std;
struct Student
{
	char name[20];
	int count;
};
int main() {
	Student s[3] = {"Tom",0,"Rain",0,"Sun",0};
	char na[20];
	for (int i = 0; i < 10; i++) {
		cin >> na;
		//以下对分支if可以使用for+if改写
			if (strcmp(na, s[0].name)==0)//对字符数组的比较需要使用特殊函数
				s[0].count++;
			else if (strcmp(na, s[1].name)==0)
				s[1].count++;
			else if (strcmp(na, s[2].name)==0)
				s[2].count++;
	}
	
	for (int i = 0; i < 3; i++)
		cout << s[i].name << ":" << s[i].count<<endl;
}

结果:
在这里插入图片描述

1.5 指向结构体变量的指针

一个结构体变量的指针就是该变量所占据的内存段的起始地址。
指针变量也可以指向结构体数组中的元素。

  • 通过指向结构体变量的指针引用结构体变量的成员
    以下3种方式等价:

    1. 结构体变量 . 成员名
    2. (* 指针名 ). 成员名
    3. 指针名->成员名
    #include <iostream>
    #include <string>
    using namespace std;
    struct Student
    {
    	string name;
    	char sex;
    	int age;
    };
    int main() {
    	Student s;
    	Student *p = &s;
    	s.name = "yj";
    	s.age = 19;
    	s.sex = 'm';
    	p->sex = 'f';//通过指针操作结构体类型变量的成员值
    	cout << s.name << " " << s.age<<" "<<s.sex<<endl;        //yj 19 f
    	cout << (*p).name << " " << (*p).age << " " << (*p).sex; //yj 19 f   注意*p两边的()不可以省去,因为成员运算符‘.’优先级高于‘*’优先级。此外p->name等价于(*p).name。
    	return 0;
    }
    
  • 用结构体变量和指向结构体变量的指针构成链表
    链表:

    1. 链表是一种重要的数据结构。
    2. 链表有一个头指针,它存放一个地址。该地址指向一个元素。
    3. 链表中的每一个元素称为节点。每个节点都应该包括两部分:用户需要用的实际数据和下一个节点的地址。最后一个元素不在指向其他元素,它的地址部分放一个“NULL”表示空地址。链表到此结束。
    4. 链表中各元素的地址可以是不连续的,要找某个元素,可以通过上一个元素提供的地址找到它。
    5. 链表数据结构必须使用指针和结构体变量才能实现。可以声明一个结构体类型,包含两种数据成员:一种是用户需要用的实际数据,另一种是用来存放下一个节点地址的指针变量。
#include <iostream>
#include <string>
using namespace std;
struct Student {
	int sno;
	string name;
	Student *next;
};
int main() {
	Student a, b, c;
	a.sno = 11; a.name = "Tom";
	b.sno = 22; b.name = "Sun";
	c.sno = 33; c.name = "Cloud"; 
	Student *head;
	Student *p;
	head = &a;
	a.next = &b;
	b.next = &c;
	c.next = NULL;
	p = head;
	do {
		cout << p->sno << " " << p->name << " " <<endl;  //输出p指向的节点的数据
		p=p->next;                                       //使p指向下一个节点;相当于p=(*p).next;(*)p.next相当于a.next;
	} while (p!=NULL);                                   //输出节点c数据后,p指针为null;
	return 0;
}
输出:  11 Tom
		22 Sun
		33 Cloud

1.6 结构体类型数据作为函数参数

  1. 结构体变量名作为作参数
  2. 用指向结构体变量的指针作形参,结构体变量的地址作为实参
  3. 用结构体变量的引用作为函数形参,它成为实参的别名。
#include <iostream>
#include <string>
using namespace std;
struct Student {
	int sno;
	string name;
};
int main() {
	Student a, b, c;
	a.sno = 11; a.name = "Tom";
	b.sno = 22; b.name = "Sun";
	c.sno = 33; c.name = "Cloud"; 
	void print(Student s);
	void print(Student *p);
	void print1(Student &ss);
	print(a);    //Tom 11
	print(&b);   //Sun 22
	print1(c);   //Cloud 33
	return 0;
}
//1. 结构体变量名作为作参数
void print(Student s) {
	cout << s.name << " " << s.sno << endl;
}
//2. 用指向结构体变量的指针作形参,结构体变量的地址作为实参
void print(Student *p) {
	cout << p->name << " " << p->sno;
}
//3. 用结构体变量的引用作为函数形参,它成为实参的别名。
void print1(Student &s) {
	cout << s.name << " " << s.sno << endl;
}

二、动态空间分配与释放

c语言中,使用库函数malloc和free来分配和撤销内存空间。
c++提供运算符new和delete来取代malloc和free函数。

  • new 和delete是运算符,而不是函数,执行效率高。

2.1 动态空间分配

一般形式:
new 类型[初值]

  1. 用new分配数组空间时不可以指定初值。
  2. 若因为内存原因而导致不能正常分配空间,new会返回一个空指针。
new int;     //开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针);
new int(100);//开辟一个存放整数的存储空间,并且初值为100,返回一个指向该存储空间的地址(即指针);

new char[10];//开辟一个存放字符数组的空间,返回一个指向字符数组首元素的地址(即指针);
new int[4][3];//开辟一个存放二维整型数组的空间,返回一个指向该数组首元素的地址(即指针);

float *p = new float(3.14);//开辟一个存放单精度数的空间,并指定初值为3.14,将返回的该空间的地址赋给指针变量p

2.2 动态空间释放

delete 指针变量------- --对变量
delete [] 指针变量 -------对数组

char *p1=new char[10];//开辟一个存放字符数组的空间,返回一个指向字符数组首元素的地址(即指针);
delete[]  p1;         //释放开辟的空间

int **p2 =new int[4][3]; //错误(活动)	E0144	"int (*)[3]" 类型的值不能用于初始化 "int **" 类型的实体,  C2440	“初始化” : 无法从“int(*)[3]”转换为“int **”
delete[] p2;

float *p = new float(float(3.14));//开辟一个存放单精度数的空间,并指定初值为3.14,将返回的该空间的地址赋给指针变量p
delete p;//释放开辟的空间

三、枚举类型——enum

  • 只要将需要的变量值一一列举出来,便构成了一个枚举类型。

  • 枚举类型的声明形式如下:
    enum 枚举类型名 {变量值列表};

    例如:
    enum Weekday
    {SUN, MON, TUE, WED, THU, FRI, SAT};

  • 枚举类型应用说明:

    1. 对枚举元素按常量处理,不能对它们赋值。例如,不能写: SUN = 0;

    2. 枚举元素具有默认值,它们依次为:0,1,2,…。

    3. 也可以在声明时另行指定枚举元素的值

      如:enum Weekday {SUN=7,MON=1,TUE,WED,THU,FRI,SAT};

    4. 枚举值可以进行关系运算。

    5. 整数值不能直接赋给枚举变量,如需要将整数赋值给枚举变量,应进行强制类型转换

设某次体育比赛的结果有四种可能:胜(WIN)、负(LOSE)、平局(TIE)、比赛取(CANCEL),编写程序顺序输出这四种情况。
在这里插入图片描述

四、typedef语句

  • 为一个已有的数据类型另外命名

  • 语法形式
    typedef 已有类型名 新类型名表;

    例如:
    typedef double Area;
    Area a;

  • 不推荐使用,降低可读性

五、联合体

  1. 声明形式:

    union 联合名{
    	数据类型 成员名 1;
    	数据类型 成员名 2;
    	     :
    	数据类型 成员名 n;
    };
    
    例如:
    union uarea{   
    	 char c_data;
    	 short s_data;
    	 long l_data;
    };
    
  2. 联合体类型变量说明的语法形式
    联合名 联合变量名;

  3. 引用形式:
    联合名.成员名

  4. 无名联合
    无名联合没有标记名,只是声明一个成员项的集合,这些成员项具有相同的内存地址,可以由成员项的名字直接访问。

    例:
    union{ 
    	int i;
    	float f;
    }
    在程序中可以这样使用:
    i=10;
    f=2.2;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值