自定义数据类型与命名空间

结构类型

结构也称为结构体,结构体的成员可以自定义,用来保存相关的复杂数据。

可以使用指定成员初始化或顺序初始化两种方式初始化结构变量。

结构变量可以通过 . 点 操作符访问成员变量。结构变量指针可以通过 -> 箭头 操作符直接访问结构成员。

//	定义结构类型
struct Student
{
	int no; //	学号
	char gender; //	性别
	int age; //	年龄
	float chieseScore; // 语文成绩
	float mathScore; // 数学成绩
} s3, s4; //    定义结构类型的同时定义结构变量

void show(Student s);

int main()
{	
	//	定义结构变量
	Student s1, s2;

	//	指定成员初始化
	s1.no = 10000; 
	s1.age = 16;
	s1.gender = 'm';
	s1.chieseScore = 99;
	s1.mathScore = 100;
	
	//	顺序初始化
	s2 = { 10001, 'f', 17, 100, 99};

	show(s1);
	show(s2);

	s3 = { 10003, 'f', 16, 80, 80 };
	show(s3);
	
	//	结构变量通过.操作符访问成员
	s3.mathScore = 100;
	Student* p = &s3;
	//	结构指针可以使用->操作符,直接访问结构的成员。 
	p->chieseScore = 100; // 相当于(*p).chinseScore = 100,常用->操作符。
	show(s3);
	//	Student占用20字节,结构体中各个成员的存储空间是独立的。
	cout << "sizeof(s3): " << sizeof(s3) << endl;

	return 0;
}

void show(Student s)
{
	cout << "学号:" << s.no << " 性别:" << s.gender << " 年龄:" << s.age
		<< " 语文成绩:" << s.chieseScore << " 数学成绩:" << s.mathScore << endl;
}

结构类型允许嵌套,即结构类型中可以使用其他结构类型变量作为成员。嵌套不允许使用结构类型本身的变量作为成员,但可以使用结构类型本身的指针作为成员。

//	定义结构类型
struct Date
{
	int year;
	int month;
	int day;
};


struct Student
{
	int no; //	学号
	char gender; //	性别
	int age; //	年龄
	float chieseScore; // 语文成绩
	float mathScore; // 数学成绩
	//	结构类型嵌套。结构体中可以使用其他结构类型作为成员
	Date birthday;	
	/*
		嵌套不允许使用结构类型本身的变量作为成员,但可以使用结构类型本身的指针作为成员。
		Student s;  不允许
		Student *p; 允许
	*/
};

void show(Student s);


int main()
{
	Student s1, s2;
	//	指定成员初始化
	s1.no = 10000;
	s1.age = 16;
	s1.gender = 'm';
	s1.chieseScore = 99;
	s1.mathScore = 100;
	s1.birthday.year = 2000;
	s1.birthday.month = 1;
	s1.birthday.day = 1;
	show(s1);

	//	顺序初始化
	s2 = { 10001, 'f', 17, 100, 99, {1999, 1, 2} };
	show(s2);

	return 0;
}

void show(Student s)
{
	cout << "学号:" << s.no << " 性别:" << s.gender << " 年龄:" << s.age
		<< " 语文成绩:" << s.chieseScore << " 数学成绩:" << s.mathScore 
		<< " 出生日期:" << s.birthday.year << "-" << s.birthday.month << "-" << s.birthday.day 
		<< endl;
}

结构体的简洁名称(起别名)

//	声明结构体时起别名
typedef struct Student S;

//	定义结构类型简洁名称
typedef struct Student
{
	int no; //	学号
	char gender; //	性别
	int age; //	年龄
	float chieseScore; // 语文成绩
	float mathScore; // 数学成绩
} s3, s4; // s3,s4是Student的别名

//	typedef定义结构的简洁名称。
typedef struct Student S2;

void show(Student s);

int main()
{
	s3 ss1 = { 10001, 'f', 17, 100, 99 };
	s4 ss2 = { 10002, 'm', 16, 98, 99 };
	S  ss3 = { 10003, 'f', 17, 99, 99 };
	S2  ss4 = { 10004, 'f', 17, 99, 99 };
	show(ss1);
	show(ss2);
	show(ss3);
	show(ss4);
	return 0;
}

void show(Student s)
{
	cout << "学号:" << s.no << " 性别:" << s.gender << " 年龄:" << s.age
		<< " 语文成绩:" << s.chieseScore << " 数学成绩:" << s.mathScore << endl;
}

结构数组与结构指针

//	定义结构类型
struct Student
{
	int no; //	学号
	char gender; //	性别
	int age; //	年龄
	float chieseScore; // 语文成绩
	float mathScore; // 数学成绩
};

int getBestChineseScoreStudentID(Student* p, int n);

int getBestChineseScoreStudentID1(Student* p, int n);

int main()
{
	Student s[5] = {
		{10000, 'f', 16, 85, 99},
		{10001, 'm', 17, 86, 98},
		{10002, 'f', 18, 87, 97},
		{10003, 'm', 19, 88, 96},
		{10004, 'f', 15, 89, 95},
	};
	
	cout << getBestChineseScoreStudentID1(s, 5) << endl;
}

int getBestChineseScoreStudentID(Student* p, int n)
{	
	//	定义指针p1指向数组p的首地址
	Student* p1 = p;

	for (int i = 0; i < n; i++)
	{
		//	如果p1指向元素的chieseScore成员小于数组p的第i个元素的chieseScore成员
		if (p1->chieseScore < p[i].chieseScore)
		{
			p1 = p + i; //	p1指向数组p的第i个元素
		}
	}
	return p1->no;
}

int getBestChineseScoreStudentID1(Student* p, int n)
{
	int no = p[0].no, score = p[0].chieseScore;
	

	for (int i = 0; i < n; i++)
	{
		
		if (score < p[i].chieseScore)
		{
			no = p[i].no;
			score = p[i].chieseScore;
		}
	}
	return no;
}

联合类型、

联合可以使几个不同变量,占用同一内存空间。

//	定义联合类型
union MyData
{
	int i;
	char c;
	double d;
};

int main()
{
	
	cout << "sizeof(MyData): " << sizeof(MyData) << endl;

	//	定义联合类型变量
	MyData d;

	//	联合类型变量的成员共用一块内存区域
	d.i = 97;
	cout << "d.i: " << d.i << " d.c: " << d.c << " d.d: " << d.d << endl;
	d.c = 'b';
	cout << "d.i: " << d.i << " d.c: " << d.c << " d.d: " << d.d << endl;

	cout << "&d.i: " << &d.i << " &d.c: " << (void*) & d.c << " &d.d" << &d.d << endl;

	return 0;
}

枚举类型

枚举是用标识符表示的整型常量的集合。

/*
	定义枚举类型
	枚举类型定义中各个枚举类型不能同名。
	如果不指定枚举元素的起始值,将自动从0开始为各个枚举类型设置初值,后面的元素自动增加1。
	enum weekday {Sun, Mon, Tue, Wed, Thu, Fri, Sat}; // 0, 1, 2, 3, 4, 5, 6, 7
	如果指定某个枚元素的值,则下一枚举元素没有指定值,就是上一个枚举元素的值增加1。
	enum weekday {Sun = 100, Mon, Tue, Wed, Thu, Fri, Sat}; // 100, 101, 102, 103, 104, 105, 106
	enum weekday {Sun = 100, Mon, Tue = 200, Wed, Thu, Fri, Sat}; // 100, 101, 200, 201, 202, 203, 204
*/
enum weekday {Sun, Mon, Tue , Wed, Thu, Fri, Sat};

int main()
{
	cout << "Sun: " << Sun << endl;
	cout << "Mon: " << Mon << endl;
	cout << "Tue: " << Tue << endl;
	cout << "Wed: " << Wed << endl;
	cout << "Thu: " << Thu << endl;
	cout << "Fri: " << Fri << endl;
	cout << "Sat: " << Sat << endl;
	int n;
	cin >> n;
	switch(n)
	{
	case Sun:
		cout << "星期日" << endl;
		break;
	case Mon:
		cout << "星期一" << endl;
		break;
	case Tue:
		cout << "星期二" << endl;
		break;
	default:
		cout << "请输入0到2的整数" << endl;
		break;
	}
	return 0;
}

命名空间

随着程序规模的不断扩大,处理名称冲突问题就越来越麻烦,为此C++引入了一个新机制,即命名空间(也叫名称空间)。

定义

命名空间只能在全局范围内定义,命名空间允许嵌套。

一个命名空间可以是另一个命名空间的别名。

使用

using namespace 命名空间; 使用命名空间中所有的标识符。

using 命名空间::成员;使用命名空间中指定的成员。

命名空间::成员,通过命名空间和::(域运算符)访问指定的成员。

//	使用命名空间中所有的标识符
using namespace std;

//	指定使用命名空间中的某个成员。
using std::cout;
using std::endl;

//	定义命名空间
namespace NS1
{
	int a = 10;

	void f1()
	{
		cout << "NS1 f1()" << endl;
	}

	//	命名空间允许嵌套
	namespace NS2
	{
		int a2 = 20;
		void f2()
		{
			cout << "NS2 f2()" << endl;
		}
	}
}

using namespace NS1;
//using namespace NS1::NS2;

//	ns2命名空间,是NS1::NS2的别名
namespace ns2 = NS1::NS2;

using  NS1::NS2::f2;


int main()
{
	//	通过域运算符访问命名空间中的成员。
	cout << NS1::a << endl;
	NS1::f1();
	cout << NS1::NS2::a2 << endl;
	//	访问NS1中的NS2命名空间中的f2()成员函数。
	NS1::NS2::f2();

	//	using namespace NS1; 使用NS1中全的成员,此时可以直接通过NS2::访问NS2中的成员。
	NS2::f2();
	//	using namespace NS1::NS2;使用NS2命名空间中所有的成员,此时可以直接访问f2()。
	f2();
	
	//	通过ns2命名空间访问NS1::NS2命名空间
	ns2::f2();	

	return 0;
}

多文件组织

一个项目由多个(.c)文件,(.h)文件和主函数文件组成。

//  Point.h 文件
/*
	编译预处理指令
	#include <文件名> 或 #include "文件名" 导入库或头文件
	#define 标识符 字符串 宏定义。
	条件编译:
	#ifndef 标识符
	程序段1
	#else
	程序段2
	#endif
*/

#ifndef POINT_H
#define POINT_H
struct Point
{
	int x;
	int y;
};

#endif

// Rectangle.h 文件

#ifndef RECTANGLE_H
#define RECTANGLE_H
#include "Point.h"

struct Rectangle
{
	Point center;
	int length;
	int width;
};
//	计算矩形面积
int area(Rectangle& r);

//	计算矩形周长
int perimeter(Rectangle& r);

#endif

// Rectangle.c 文件

#include "Rectangle.h"

int area(Rectangle& r)
{
	return r.width * r.length;
}

int perimeter(Rectangle& r)
{
	return 2*(r.width + r.length);
}

// Circle.h 文件

#ifndef CIRCLE_H
#define CIRCLE_H
#include "Point.h"
struct Circle
{
	Point center;
	int radius;
};

int area(Circle& c);
int perimeter(Circle& c);
#endif

//    Circle.c 文件
#include "Circle.h"

const float PI = 3.1415926;

int area(Circle& c)
{
	return PI * c.radius * c.radius;
}
int perimeter(Circle& c)
{
	return 2* PI * c.radius;
}

// Main.c 文件

#include <iostream>
#include "Point.h"
#include "Rectangle.h"
#include "Circle.h"
using namespace std;



int main()
{
	Point point1 = { 1, 1 };

	cout << point1.x << ", " << point1.y << endl;

	Rectangle r = { {2, 2}, 1, 1 };

	cout << "area(r): " << area(r) << endl;
	cout << "perimeter(r):" << perimeter(r) << endl;
	
	Circle c = { {0, 0} , 3 };

	cout << "area(c): " << area(c) << endl;
	cout << "perimeter(c):" << perimeter(c) << endl;

	return 0;
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值