14.复杂数据类型-结构体
14.1 知识点
基本概念
结构体
结构体是一种自定义变量类型,类似枚举需要自己定义。它是数据和函数的集合,用于表现存在关系的数据集合,例如学生、动物、人类等。
基本语法
结构体一般写在 namespace
语句块中
- 结构体关键字
struct
- 结构体名采用帕斯卡命名法
// struct 自定义结构体名
// {
// // 第一部分
// // 变量
// // 第二部分
// // 构造函数(可选)
// // 第三部分
// // 函数
// }
实例
声明结构体和声明结构体变量
- 声明结构体相当于创建自定义变量类型
- 声明结构体变量相当于使用自定义变量类型声明变量
namespace YourNamespace
{
// 声明表现学生数据的结构体
struct Student
{
// 变量
public int age;
public bool sex;
public int number;
public string name;
// 构造函数
// 函数方法
public void Speak()
{
// 函数中可以直接使用结构体内部声明的变量
Console.WriteLine("我的名字是{0},我今年{1}岁", name, age);
}
// 可以根据需求写无数个函数的
}
}
结构体的使用
主函数内
- 声明结构体变量
- 修改结构体变量的内部变量
- 调用结构体的函数
- 使用结构体的构造函数声明结构体变量
// 变量类型 变量名;
Student s1;
// 修改结构体变量的内部变量
s1.age = 10;
s1.sex = false;
s1.number = 1;
s1.name = "韬老狮";
// 调用结构体的函数
s1.Speak();
// 使用结构体的构造函数声明结构体变量
Student s2 = new Student(18, true, 2, "小红");
s2.Speak();
访问修饰符
- 修饰结构体中变量和方法是否能被外部使用
public
:公共的,可以被外部访问private
:私有的,只能在内部使用,默认不写为私有
构造函数
基本概念
- 没有返回值
- 函数名必须和结构体名相同
- 必须有参数
- 如果声明了构造函数,必须在其中对所有变量数据初始化
结构体语句块内
// 构造函数一般是用于在外部方便初始化的
public Student(int age, bool sex, int number, string name)
{
// 新的关键字 this
// 代表自己
this.age = age;
this.sex = sex;
this.number = number;
this.name = name;
}
总结
- 概念: 结构体
struct
是变量和函数的集合,用来表示特定的数据集合。 - 访问修饰符:
public
和private
用来修饰变量和方法,public
外部可以调用,private
内部用,不写的话默认是私有。 - 构造函数: 没有返回值,函数名和结构体名相同,可以重载,主要帮助快速初始化结构体对象。注意在结构体中声明的变量不能初始化,只能在外部或者在函数中赋值(初始化)。在结构体中声明的函数不需要加
static
。
14.2 知识点代码
using System;
namespace Lesson12_结构体
{
#region 知识点一 基本概念
//结构体 是一种自定义变量类型 类似枚举需要自己定义
//它是数据和函数的集合
//在结构体中 可以声明各种变量和方法
//作用:用来表现存在关系的数据集合 比如用结构体表现学生 动物 人类等等
#endregion
#region 知识点二 基本语法
//1.结构体一般写在 namespace语句块中
//2.结构体关键字 struct
//struct 自定义结构体名
//{
// // 第一部分
// // 变量
// // 第二部分
// // 构造函数(可选)
// // 第三部分
// // 函数
//}
// 注意 结构体名字 我们的规范 是 帕斯卡命名法
#endregion
#region 知识点三 实例
// 声明结构体 和 声明结构体变量 也是两个概念
// 声明结构体 可以理解为 自己创造一个变量类型
// 声明结构体变量 可以理解为 拿自己写的变量类型声明变量进行所使用
//namespace语句块内 class语句块外
// 声明 表现学生数据 的 结构体
struct Student
{
#region 知识点五 访问修饰符
//修饰结构体中变量和方法 是否能被外部使用
//public 公共的 可以被外部访问
//private 私有的 只能在内容使用
//默认不写 为private
#endregion
//变量
//结构体声明的变量 不能直接初始化
//变量类型 可以写任意类型 包括结构体 但是 不能是自己的结构体 可以是其它的
//Student s;// 不能是自己的结构体
//年龄
public int age;
//性别
public bool sex;
//学号
public int number;
//姓名
public string name;
//构造函数
#region 知识点六 结构体的构造函数
//基本概念
//1.没有返回值
//2.函数名必须和结构体名相同
//3.必须有参数
//4.如果声明了构造函数 那么必须在其中对所有变量数据初始化
//结构体语句块内
//构造函数 一般是用于在外部方便初始化的
public Student(int age, bool sex, int number, string name)
{
//新的关键字 this
//代表自己
this.age = age;
this.sex = sex;
this.number = number;
this.name = name;
}
#endregion
//函数方法
//表现这个数据结构的行为
//注意 在结构体中的方法 目前不需要加static关键字
public void Speak()
{
//函数中可以直接使用结构体内部声明的变量
Console.WriteLine("我的名字是{0},我今年{1}岁", name, age);
}
//可以根据需求 写无数个函数的
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("结构体");
#region 知识点四 结构体的使用
//主函数内
//声明结构体变量
//变量类型 变量名;
Student s1;
//修改结构体变量的内部变量
//要将结构体变量的内部变量的访问修饰符改成public才能在外部进行修改和访问
s1.age = 10;
s1.sex = false;
s1.number = 1;
s1.name = "韬老狮";
//调用结构体的函数
//要将结构体的函数的访问修饰符改成public才能在外部进行修改和访问
s1.Speak();
//使用结构体的构造函数声明结构体变量
Student s2 = new Student(18, true, 2, "小红");
s2.Speak();
#endregion
}
}
// 总结
// 概念:结构体 struct 是变量和函数的集合 用来表示特定的数据集合
// 访问修饰符: public 和private 用来修饰变量和方法的 public 外部可以调用 private内部用 不写的话默认就是private
// 构造函数 : 没有返回值 函数名和结构体名相同 可以重载 主要是帮助我们快速初始化结构体对象的
// 注意:
// 1.在结构体中声明的变量 不能初始化 只能在外部或者在函数中赋值(初始化)
// 2.在结构体中声明的函数 不用加static的
}
14.3 练习题
使用结构体描述学员的信息,姓名,性别,年龄,班级,专业,创建两个学员对象,并对其基本信息进行初始化并打印
namespace 语句块内 class 语句块外
struct Student
{
public string name;
public bool sex;
public int age;
public int clas;
public string major;
public Student(string name, bool sex, int age, int clas, string major)
{
this.name = name;
this.sex = sex;
this.age = age;
this.clas = clas;
this.major = major;
}
public void Speak()
{
Console.WriteLine("姓名:{0} 性别:{1} 年龄:{2} 班级:{3} 专业:{4}", name, sex ? "女" : "男", age, clas, major);
}
}
主函数内
Student s1 = new Student("韬老狮", false, 18, 3, "软件工程");
s1.Speak(); // 输出:姓名:韬老狮 性别:男 年龄:18 班级:3 专业:软件工程
Student s2;
s2.name = "小明";
s2.sex = false;
s2.age = 10;
s2.clas = 1;
s2.major = "网络工程";
s2.Speak(); // 输出:姓名:小明 性别:男 年龄:10 班级:1 专业:网络工程
请简要描述 private 和 public 两个关键字的区别
- 他们都是访问修饰符,用来修饰变量和函数。
- 如果默认不写访问修饰符,则为 private。
- private: 私有的,被它修饰的变量和函数只能在结构体内部使用,外部无法使用。
- public: 公共的,被它修饰的变量和函数能在内外都访问。
使用结构体描述矩形的信息,长,宽;创建一个矩形,对其长宽进行初始化,并打印矩形的长、宽、面积、周长等信息。
namespace 语句块内 class 语句块外
struct Rect
{
public float w;
public float h;
public float area;
public float perimeter;
public Rect(int w, int h)
{
this.w = w;
this.h = h;
area = w * h;
perimeter = 2 * (w + h);
}
public void WriteInfo()
{
Console.WriteLine("该矩形宽为{0}高为{1}面积为{2}周长为{3}", w, h, area, perimeter);
}
}
主函数内
Rect r = new Rect(5, 4);
r.WriteInfo(); // 输出:该矩形宽为5高为4面积为20周长为18
用结构体描述玩家信息,玩家名字,玩家职业。请用户输入玩家姓名,选择玩家职业,最后打印玩家的攻击信息
namespace 语句块内 class 语句块外
// 声明玩家职业枚举
enum E_Occupation
{
Warrior,
Hunter,
Master,
}
// 声明玩家信息结构体
struct PlayerInfo
{
public string name;
public E_Occupation occupation;
public PlayerInfo(string name, E_Occupation occupation)
{
this.name = name;
this.occupation = occupation;
}
public void Atk()
{
string o = "";
string s = "";
switch (occupation)
{
case E_Occupation.Warrior:
o = "战士";
s = "冲锋";
break;
case E_Occupation.Hunter:
o = "猎人";
s = "假死";
break;
case E_Occupation.Master:
o = "法师";
s = "奥术冲击";
break;
default:
o = "无职业者";
s = "无招胜有招";
break;
}
Console.WriteLine("{0}{1}释放了{2}", o, name, s);
}
}
主函数内
Console.WriteLine("请输入你的姓名");
string name = Console.ReadLine();
Console.WriteLine("请输入职业(0战士 1猎人 2法师)");
try
{
E_Occupation o = (E_Occupation)int.Parse(Console.ReadLine());
// 根据输入的内容初始化了一个玩家对象
PlayerInfo info = new PlayerInfo(name, o);
info.Atk();
}
catch
{
Console.WriteLine("请输入数字");
}
使用结构体描述小怪兽
namespace 语句块内 class 语句块外
struct Monster
{
public string name
;
public int atk;
public Monster(string name)
{
this.name = name;
Random r = new Random();
atk = r.Next(10, 30);
}
public void Atk()
{
Console.WriteLine("{0}的攻击力是{1}", name, atk);
}
}
定义一个数组存储10个上面描述的小怪兽,每个小怪兽的名字为(小怪兽+数组下标)
主函数内
Monster[] monsters = new Monster[10];
for (int i = 0; i < monsters.Length; i++)
{
monsters[i] = new Monster("小怪兽" + i);
monsters[i].Atk();
}
实现奥特曼打小怪兽
namespace 语句块内 class 语句块外
// 声明奥特曼结构体
struct OutMan
{
public string name;
public int atk;
public int def;
public int hp;
public OutMan(string name, int atk, int def, int hp)
{
this.name = name;
this.atk = atk;
this.def = def;
this.hp = hp;
}
// 结构体是值类型,想要在函数内部改变值类型信息,外部受影响,一定记住用 ref 或者 out
public void Atk(ref Boss monster)
{
// 奥特曼打小怪兽的逻辑
monster.hp -= atk - monster.def;
Console.WriteLine("{0}攻击了{1},造成了{2}伤害,{3}剩余血量{4}", name, monster.name, atk - monster.def, monster.name, monster.hp);
}
}
// 声明怪兽结构体
struct Boss
{
public string name;
public int atk;
public int def;
public int hp;
public Boss(string name, int atk, int def, int hp)
{
this.name = name;
this.atk = atk;
this.def = def;
this.hp = hp;
}
public void Atk(ref OutMan outMan)
{
// 小怪兽打奥特曼的逻辑
outMan.hp -= atk - outMan.def;
Console.WriteLine("{0}攻击了{1},造成了{2}伤害,{3}剩余血量{4}", name, outMan.name, atk - outMan.def, outMan.name, outMan.hp);
}
}
主函数内
OutMan outMan = new OutMan("雷欧奥特曼", 10, 5, 100);
Boss boss = new Boss("哥斯拉", 8, 4, 100);
while (true)
{
outMan.Atk(ref boss);
if (boss.hp <= 0)
{
Console.WriteLine("{0}胜利", outMan.name);
break;
}
boss.Atk(ref outMan);
if (outMan.hp <= 0)
{
Console.WriteLine("{1}胜利", boss.name);
break;
}
Console.WriteLine("按任意键继续");
Console.ReadKey(true);
}
14.4 练习题代码
using System;
namespace Lesson12_练习题
{
#region 练习题一
//使用结构体描述学员的信息,姓名,性别,年龄,班级,专业,
//创建两个学员对象,并对其基本信息进行初始化并打印
//namespace语句块内 class语句块外
struct Student
{
public string name;
public bool sex;
public int age;
public int clas;
public string major;
public Student(string name, bool sex, int age, int clas, string major)
{
this.name = name;
this.sex = sex;
this.age = age;
this.clas = clas;
this.major = major;
}
public void Speak()
{
Console.WriteLine("姓名:{0}性别:{1}年龄:{2}班级:{3}专业:{4}", name, sex ? "女":"男", age, clas, major);
}
}
#endregion
#region 练习题二
//请简要描述private和public两个关键字的区别
// 他们都是访问修饰符 用来修饰变量和函数的
// 如果默认不写访问修饰符 则为private
// private 私有的 被它修饰的变量和函数只能在结构体内部使用 外部无法使用
// public 公共的 被它修饰的变量和函数 能在内外都访问
#endregion
#region 练习题三
//使用结构体描述矩形的信息,长,宽;创建一个矩形,
//对其长宽进行初始化,并打印矩形的长、宽、面积、周长等信息。
//namespace语句块内 class语句块外
struct Rect
{
public float w;
public float h;
public float area;
public float perimeter;
public Rect(int w, int h)
{
this.w = w;
this.h = h;
area = w * h;
perimeter = 2 * (w + h);
}
public void WriteInfo()
{
Console.WriteLine("该矩形宽为{0}高为{1}面积为{2}周长为{3}", w, h, area, perimeter);
}
}
#endregion
#region 练习题四
//使用结构体描述玩家信息,玩家名字,玩家职业
//请用户输入玩家姓名,选择玩家职业,最后打印玩家的攻击信息
//职业:
//战士(技能:冲锋)
//猎人(技能:假死)
//法师(技能:奥术冲击)
//打印结果:猎人韬老狮释放了假死
//namespace语句块内 class语句块外
//声明玩家信息结构体
struct PlayerInfo
{
public string name;
public E_Occupation occupation;
public PlayerInfo(string name, E_Occupation occupation)
{
this.name = name;
this.occupation = occupation;
}
public void Atk()
{
string o = "";
string s = "";
switch (occupation)
{
case E_Occupation.Warrior:
o = "战士";
s = "冲锋";
//Console.WriteLine("战士{0}释放了冲锋");
break;
case E_Occupation.Hunter:
o = "猎人";
s = "假死";
//Console.WriteLine("猎人{0}释放了假死");
break;
case E_Occupation.Master:
o = "法师";
s = "奥术冲击";
//Console.WriteLine("法师0}释放了奥数冲击");
break;
default:
o = "无职业者";
s = "无招胜有招";
break;
}
Console.WriteLine("{0}{1}释放了{2}", o, name, s);
}
}
//声明玩家职业枚举
enum E_Occupation
{
/// <summary>
/// 战士
/// </summary>
Warrior,
/// <summary>
/// 猎人
/// </summary>
Hunter,
/// <summary>
/// 法师
/// </summary>
Master,
}
#endregion
#region 练习题五
//使用结构体描述小怪兽
//namespace语句块内 class语句块外
struct Monster
{
public string name;
public int atk;
public Monster(string name)
{
this.name = name;
Random r = new Random();
atk = r.Next(10, 30);
}
public void Atk()
{
Console.WriteLine("{0}的攻击力是{1}", name, atk);
}
}
#endregion
#region 练习题六
//定义一个数组存储10个上面描述的小怪兽,每个小怪兽的名字为(小怪兽+数组下标)
//举例:小怪兽0,最后打印10个小怪兽的名字+攻击力数值
#endregion
#region 练习题七
//应用已学过的知识,实现奥特曼打小怪兽
//提示:
//结构体描述奥特曼与小怪兽
//定义一个方法实现奥特曼攻击小怪兽
//定义一个方法实现小怪兽攻击奥特曼
//namespace语句块内 class语句块外
//声明奥特曼结构体
struct OutMan
{
public string name;
public int atk;
public int def;
public int hp;
public OutMan(string name, int atk, int def, int hp)
{
this.name = name;
this.atk = atk;
this.def = def;
this.hp = hp;
}
//结构体是值类型 想要在函数内部改变值类型信息 外部受影响 一定 记住 用 ref或者out
public void Atk( ref Boss monster )
{
//奥特曼打小怪兽的逻辑
monster.hp -= atk - monster.def;
Console.WriteLine("{0}攻击了{1},造成了{2}伤害,{3}剩余血量{4}", name, monster.name, atk - monster.def, monster.name, monster.hp);
}
}
//声明怪兽结构体
struct Boss
{
public string name;
public int atk;
public int def;
public int hp;
public Boss(string name, int atk, int def, int hp)
{
this.name = name;
this.atk = atk;
this.def = def;
this.hp = hp;
}
public void Atk(ref OutMan outMan)
{
//小怪兽打奥特曼的逻辑
outMan.hp -= atk - outMan.def;
Console.WriteLine("{0}攻击了{1},造成了{2}伤害,{3}剩余血量{4}", name, outMan.name, atk - outMan.def, outMan.name, outMan.hp);
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("结构体练习题");
#region 练习题一
//主函数内
Student s1 = new Student("韬老狮", false, 18, 3, "软件工程");
s1.Speak();//姓名:韬老狮性别:男年龄:18班级:3专业:软件工程
Student s2;
s2.name = "小明";
s2.sex = false;
s2.age = 10;
s2.clas = 1;
s2.major = "网络工程";
s2.Speak();
//姓名:小明性别:男年龄:10班级:1专业:网络工程
#endregion
#region 练习题三
//主函数内
Rect r = new Rect(5, 4);
r.WriteInfo();
//该矩形宽为5高为4面积为20周长为18
#endregion
#region 练习题四
//主函数内
Console.WriteLine("请输入你的姓名");
string name = Console.ReadLine();
Console.WriteLine("请输入职业(0战士 1猎人 2法师)");
try
{
E_Occupation o = (E_Occupation)int.Parse(Console.ReadLine());
//根据输入的内容初始化了一个玩家对象
PlayerInfo info = new PlayerInfo(name, o);
info.Atk();
}
catch
{
Console.WriteLine("请输入数字");
}
#endregion
#region 练习题六
//主函数内
//变量类型[] 数组名 = new 变量类型[10];
Monster[] monsters = new Monster[10];
for (int i = 0; i < monsters.Length; i++)
{
monsters[i] = new Monster("小怪兽" + i);
monsters[i].Atk();
}
#endregion
#region 练习题七
//主函数内
OutMan outMan = new OutMan("雷欧奥特曼", 10, 5, 100);
Boss boss = new Boss("哥斯拉", 8, 4, 100);
while(true)
{
outMan.Atk(ref boss);
if( boss.hp <= 0 )
{
Console.WriteLine("{0}胜利",outMan.name);
break;
}
boss.Atk(ref outMan);
if (outMan.hp <= 0)
{
Console.WriteLine("{1}胜利", boss.name);
break;
}
Console.WriteLine("按任意键继续");
Console.ReadKey(true);
}
#endregion
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com