跟我从零开始学C++(C++代码基础)5

引言

  小伙伴们,在经过一些基础定义和指针,数组,函数的洗礼后,我相信大家肯定都已经对C++编程有了新的认知,同时呢,坚持下来的小伙伴们肯定都是好样的,大家都是很棒的,现在我们来学一学有关C++的最后一章,这章的难度比起指针和函数,还有数组,都还算简单,不过都是一些新概念,所以小伙伴们在学习的时候也要写好笔记,同时呢也要切身实地的亲手在VS上敲一敲,这样才能对知识有个消化吸收的过程。

  好了,仍然是废话不多说,跟着小杨的节奏~冲冲冲!!!!!

自定义类型

引言
  很多时候,我们在写程序的时候一个变量里有很多小的变量,比如成绩里分为语文,数学,英语等,我们需要一个一个的把变量初始化,并每次调用的时候都需要找到正确的位置和函数。这对于看重计算速度的程序员们来说,很不方便,那有什么方式可以让我们可以更好的管理吗。
  由此,在C++中,除了一些基本类型,我们在这引入一个新的可以有用户定义的数据类型。它就是“结构体”(struct),它允许你将多个不同或相同类型的数据项组合成一个单一的实体。这可以帮助你组织数据,使其更加模块化和易于管理。

结构类型

相关知识点:

  • 结构类型也称结构体,可以使用结构变量来保存复杂数据。
  • 结构变量的初始化分为顺序初始化,指定成员初始化。
  • 可以通过“.”来访问结构变量中的成员
  • 结构类型允许使用嵌套,结构类型中可以使用其他的结构类型
  • 结构指针可以使用->直接使用其指向的结构变量的成员。
      
  • 结构变量的定义和使用
#include <iostream>

using namespace std;


//	定义结构类型
struct Student
{
	int no; // 学号
	char gender; // 性别
	float score; // 成绩
} s3; // 定义结构的同时,定义结构变量

void info(Student s);

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

	//	指定成员初始化
	s1.gender = 'f';
	s1.no = 10000;
	s1.score = 99.1;

	info(s1);
	//	顺序初始化
	s2 = { 10001, 'm', 91.1};
	s3 = { 10002, 'm', 92.1 };
	
	info(s2);
	info(s3);

	return 0;
}

void info(Student s)
{
	cout << "学号: " << s.no << " 性别: " << s.gender << " 成绩:" << s.score << endl;
}
  • 结构类型嵌套
#include <iostream>

using namespace std;

//	结构类型嵌套

struct Date
{
	int year;
	int month;
	int day;
};

struct Student
{
	int no; // 学号
	char gender; // 性别
	float score; // 成绩
	Date birth; // 生日
	//	不允许使用结构体本身 Student s;
}; 

void info(Student s);

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

	//	指定成员初始化
	s1.gender = 'f';
	s1.no = 10000;
	s1.score = 99.1;
	s1.birth.month = 10;
	s1.birth.year = 2000;
	s1.birth.day = 1;
	info(s1);
	//	顺序初始化
	s2 = { 10001, 'm', 91.1, {2000, 1, 1} };
	
	info(s2);
	
	return 0;
}

void info(Student s)
{
	cout << "学号: " << s.no << " 性别: " << s.gender << " 成绩:" << s.score ;
	cout << " 出生日期:" << s.birth.year << "-" << s.birth.month << "-" << s.birth.day << endl;
}
  • 简洁名称
#include <iostream>

using namespace std;

//	使用typedef定义结构类型的简洁名称
typedef struct Student
{
	int no; // 学号
	char gender; // 性别
	float score; // 成绩
} stu1, stu2; //	定义结构变量的同时定义简洁名称

void info(Student s)
{
	cout << "学号: " << s.no << " 性别: " << s.gender << " 成绩:" << s.score << endl;
}  
//	定义带参函数info(s),参数是结构体类型,返回值是void型;


//	声明结构类型时使用typedef定义简洁名称
typedef struct Dog
{
	int age;
	int type;

}D;
void info2(Dog g)
{
	cout <<"小狗的年龄是"<< g.age<<"岁。   小狗的种类是" << g.type << endl;
}


int main()
{
	stu1 s1 = {1000, 'f', 99.9};
	stu2 s2 = { 1001, 'm', 99.0 };
	info(s1);
	info(s2);
	D d1 = { 1,23};
	info2(d1);
	
}



  • 结构数组
#include <iostream>

using namespace std;

struct Student
{
	int no; // 学号
	char gender; // 性别
	float score; // 成绩
};

void info(Student s)
{
	cout << "学号: " << s.no << " 性别: " << s.gender << " 成绩:" << s.score << endl;
}

int main()
{
	//	定义结构数组
	Student s[5] = {
		{1000, 'f', 80.1},
		{1001, 'm', 89.1},
		{1002, 'f', 99.1},
		{1003, 'm', 70.1},
		{1004, 'f', 92.1},
	};

	//	获取成绩最高的同学的学号
	Student s1 = s[0];
	cout << "&s1" << &s1 << endl;

	for (int i = 0; i < 5; i++)
	{
		if (s[i].score > s1.score)
		{
			s1 = s[i];
			cout << "&s1" << &s1 << endl;
		}
	}
	info(s1);

}


  • 结构指针
#include <iostream>

using namespace std;

struct Student
{
	int no; // 学号
	char gender; // 性别
	float score; // 成绩	
};

void info(Student s)
{
	cout << "学号: " << s.no << " 性别: " << s.gender << " 成绩:" << s.score << endl;
}

float average(Student* p, int n);

int main()
{
	//	定义结构数组
	Student s[5] = {
		{1000, 'f', 80.1},
		{1001, 'm', 89.1},
		{1002, 'f', 99.1},
		{1003, 'm', 70.1},
		{1004, 'f', 92.1},
	};

	//	获取成绩最高的同学的学号
	Student* s1 = s;
	
	for (int i = 0; i < 5; i++)
	{
		//	结构指针可以使用->直接访问其指向的结构变量的成员
		if (s[i].score > s1->score)
		{
			//	&s[i] : &(*(s + i))
			s1 = (s + i); // 通过指针算数运算符获取地址
			
		}
	}
	info(*s1);
	cout << average(s, 5) << endl;
	cout << "sizeof(Student): " << sizeof(Student) << endl;
	return 0;
}

float average(Student* p, int n)
{
	float sum = 0;
	for (int i = 0; i < n; i++)
	{
		sum += (p + i) -> score;
	}
	return sum / n;
}

联合类型

  • 联合可以使几个不同变量占用同一内存空间。联合类型也称共同体
#include <iostream>

using namespace std;

//	定义联合类型
//	联合类型就是所有元素都指向一个变量,变量改变一个,其他的都跟着变
union my_data
{
	int i;	
	char c;
	float f;
};

int main()
{
	cout << "sizeof(my_data): " << sizeof(my_data) << endl;
	//	定义联合类型变量
	my_data m;
	//	使用联合类型变量
	m.i = 97;
	cout << "m.c: " << m.c << endl;
	cout << "m.f: " << m.f << endl;
	m.c = 'b';
	cout << "m.i: " << m.i << endl;
	cout << "m.f: " << m.f << endl;
}

结构和联合的区别

  • 结构类型:多个变量有独立的存储空间,一个变量改变了,其他变量不跟着改变。
  • 联合类型:多个变量共享存储空间,一个变量改变了,其他变量也跟着改变。

枚举

  • 枚举是用标识符表示的整数型常量的集合。
#include <iostream>

using namespace std;

//	定义枚举类型
enum weekdays {Sun, Mon, Tue, Wed, Thu, Fri, Sat}; // 枚据类型默认从0开始, 0, 1, 2, 3, 4, 5, 6

/*
	枚据类型各元素不能同名。
	如果不指定枚举类型元素的值,将自动从0开始为各个元素设置初值,后面的元素依次递增1.
	如果指定某个元素的值,则下一个元素如果没有指定值,就是上一个元素值加1。

enum weekdays { Sun , Mon, Tue = 7, Wed = 10, 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 day = 1;
	switch (day)
	{
	case Sun:
		cout << "星期日" << endl;
		break;
	case Mon:
		cout << "星期一" << endl;
		break;
	default:
		break;
	}

	return 0;
}

命名空间

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

  • 命名空间只能在全局范围内定义,命名空间允许嵌套。
  • 一个命名空间可以用另一个命名空间作为别名。
  • 使用域运算符::获取命名空间中的元素
  • using namespace 命名空间,使用命名空间中所有的元素。
#include <iostream>

//	using namespace 使用命名空间中所有的元素
using namespace std;

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

	void f1()
	{
		cout << "NS1::f1()" << endl;
	}
	//	命名空间允许嵌套
	namespace NS2
	{
		int b = 10;
		void f2()
		{
			cout << "NS2::f2()" << endl;
		}
	}
}

namespace NS3
{
	int a = 30;
	void f1()
	{
		cout << "NS3::f1()" << endl;
	}
}



//	一个命名空间可以用另一个命名空间作为别名  
namespace ns2 = NS1::NS2;

//	使用一个命名空间中所有的成员  
using namespace NS3;


int main()
{
	//	使用域运算符::获取命名空间中的元素
	cout << NS1::a << endl;
	NS1::f1();
	NS1::NS2::f2();
	cout << ns2::b << endl;

	cout << a << endl;
	f1();

	return 0;
}

多文件组织

引言
  随着我们写的代码越来越多,程序越来越复杂,当我们面对大型复杂项目时,我们往往会把代码模块化分开,让小组内成员分工合作完成一个整体,而作为一个总程序,我们只有一个main函数,所以一些功能函数,还有一些其他变量我们会分在其他文件里写,再根据法则去链接整个文件组织,使其成为一个整体。这就是为什么我们看到的一些项目都是大包小包的原因,现在我们也来学习一下,如何利用多文件组织。

相关知识点:

  • 头文件(.h),一般存放数据结构定义,函数声明,全局常量,类声明等。
  • 源文件(.cpp),源文件存放函数实现,类方法实现,等各种功能的实现。
  • 编译预处理指令
    • 文件包含,#include<文件名>或#include “文件名”
    • 宏定义,#define 标识符 字符串,如 #define PI 3.1415926等
    • 条件编译, #ifndef #else #endif

示例展示:
在这里插入图片描述

代码示例:
我们先创建一个cpp源文件,并写下如下代码

Main.cpp

#include <iostream>

#include "Point.h"
#include "Rectangle.h"
#include "Circle.h"

using namespace std;

int main()
{
	Point point1 = { 1, 1 };
	Rectangle r = { point1, 2, 3 };
	cout << area(r) << endl;
	cout << perimeter(r) << endl;
	
	Circle c = { point1, 3 };
	cout << area(c) << endl;
	cout << perimeter(c) << endl;

	return 0;
}

Circle.cpp

#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;
}

Rectangle.cpp

#include "Rectangle.h"

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

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

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

Point.h

/*
	编译预处理指令,条件编译。
	#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

  小伙伴们有关多文件组织的内容,可能只看代码和讲解并不能第一时间看懂,建议大家在学习的时候也看看视频资料,这方面小杨也在准备了,相信不久大家就可以相关链接。

结语

  哇~,小伙伴们终于在半个多月的时间内,大家把有关C++的基础课学完了哟,撒花❀❀❀!!!小伙伴们一定要及时复习把最近学到的内容学到炉火纯青哟,稍后,小杨会给大家带来C++的进阶课程,面向对象编程,这是C++的又一大难点,如果大家的基础好的话,会在后边的课程中才能学的轻松,不然后边的内容就会磕磕绊绊。

  好了,不管怎么说,大家都很棒,为自己鼓鼓掌!!!接下来也要加油呀!!!冲冲冲!!!

  • 31
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值