这是「C# 学习加固」系列的第 2 篇,共 5 篇;可通过文末的系列导航继续阅读。
18. 函数的基本使用#
函数的基本使用#
函数一般也叫方法,将可以复用的代码包装起来,方便之后调用

private void Start()
{
int num = 100;
Function(num,"Test"); //调用函数
Debug.Log($"实参num = {num}"); //输出 num 的值
int num2 = 33;
num2 = Add(num2, 333);
Debug.Log($"Add(100, 333) = {num2}"); // 输出 Add 函数的返回值
}
// 函数的参数名称理论是无所谓是什么的,但是还是要见名知意
// 函数的参数叫做形参,也就是形式参数,和外部调用处的函数变量名称没有关系
// 实参和形参没有关系:一方改变不影响另外一方,相当于变成了两个类型一致但是数值没有关联的变量
void Function(int num,string info)
{
num += 200;
for (int i = 0; i <= 100; i++)
{
//Debug.Log($"{i}");
}
Debug.Log($"形参num : {num}");
}
// 一个返回值类型为int的函数
int Add(int a, int b)
{
int res = a + b;
return res; // return的结果要跟函数的返回值类型一致
}
void Do()
{
return; //return意味着不执行之后的逻辑
}19. 函数重载#
同名函数不同参数称之为重载
private void Start()
{
int res = Add(1, 2);
int res2 = Add(1, 2, 3);
int res3 = Add(1, "2");
}
int Add(int a, int b)
{
int res = a + b;
return res; // return的结果要跟函数的返回值类型一致
}
// int.Parse:转为int类型
int Add(int a, string b)
{
int res = a + int.Parse(b);
return res;
}
int Add(int a, int b, int c)
{
int res = a + b + c;
return res;
}20. 函数的ref和out关键字#
ref:通常情况下,形参和实参只是值一样,但是并不是同一个变量。如果通过ref则可以视为一个变量
out:函数的返回值只有一个,如果希望有两个及以上,则可以使用
函数的参数可以有默认值,在定义的时候直接=即可
private void Start()
{
int a = 3;
RefFunction(ref a); // 实参
Debug.Log($"实参: {a}");
// 需求:
// 1.请求登录,提供一个账号
///2.如果有此账号,返回true,并且返回密码
if (CheckLogin("user123", out string password)) // 相当于定义在if的外面
{
Debug.Log($"登录成功,密码是:{password}");
}
else
{
Debug.Log("登录失败,账号不存在");
}
TestFunction(100,200);
TestFunction(10);
TestFunction(1);
}
void RefFunction(ref int a) // 形参
{
a += 1000;
Debug.Log($"形参: {a}");
}
/// <summary>
/// 检查登录
/// </summary>
/// <param name="account">用户名</param>
/// <param name="password">密码</param>
/// <returns>是否登录成功</returns>
bool CheckLogin(string account, out string password)
{
// 模拟账号和密码
if (account == "user123")
{
password = "password123"; // 返回密码
return true; // 登录成功
}
else
{
password = null; // 无效账号
return false; // 登录失败
}
}
// 测试可选参数(默认参数)
// 如果你传递,则使用传递的值;如果不传递,则使用默认值
void TestFunction(int c,int a = 10099, int b = 9999)
{
Debug.Log(a+b+c);
}21. 结构体#
结构体是一种自定义类型,用于创建我们游戏或者实际业务中的自定义类型
比如Moba游戏中的英雄角色,那必然存在英雄的血量、攻击力、等级等关键属性,这些属性我们可以用int、float等类型来描述,但是往往我们需要打包来使用,因为我们往往需要“这个英雄的攻击力”、“这个英雄的防御力”、我们会可以抽象出“英雄”这个数据概念。所以我们可以创建一个“英雄类型”。
同时也为我们之后学习非常重要的“类”做一个铺垫
using UnityEngine;
public class Hello : MonoBehaviour
{
private void Start()
{
Hero tanke = new Hero(); // 构造一个结构体
tanke.Name = "超级坦克"; // 修改结构体的成员变量
Debug.Log($"英雄: {tanke.Name}");
tanke.Show(); // 调用结构体的成员函数
Hero tanke2 = new Hero("X刺客", 30, 500); // 构造另一个结构体
tanke2.Show(); // 调用另一个结构体的成员函数
}
}
/// <summary>
/// 英雄结构体
/// </summary>
struct Hero
{
// 成员
// 成员字段(变量)
// 访问修饰符
// 1. public: 公共的,可以被外部访问
// 2. private: 私有的,只能在结构体内部访问
public string Name; // 默认值是 null
public int Attack; // 成员存在默认值,数值类型(int, float, double)默认值是 0
public int Hp;
// 默认有一个无参构造函数
// 构造函数
public Hero(string name, int attack, int hp)
{
Name = name;
Attack = attack;
Hp = hp;
}
// 成员函数
public void Show()
{
Debug.Log($"英雄: {Name}, 攻击力: {Attack}, 生命值: {Hp}");
}
}22. 结构体使用细节#
构造函数也可以重载
this关键字
代表着当前对象,也就是在外部声明的变量
访问修饰符详解
private修饰的成员外界无法访问,只能在结构体内部使用
public修饰的成员,外界和内部都可以随意使用
using UnityEngine;
public class Hello : MonoBehaviour
{
private void Start()
{
Hero tanke2 = new Hero("X刺客", 30, 500); // 构造另一个结构体
tanke2.Show(); // 调用另一个结构体的成员函数
HeroClass mage = new HeroClass("法师", 50); // 构造一个类
mage.Show(); // 调用类的成员函数
// 结构体和类的区别
// 1. 结构体是值类型,类是引用类型
// 2. 结构体的实例在栈上分配内存,类的实例在堆上分配内存
// 3. 结构体的实例在赋值时会复制所有成员,类的实例在赋值时只复制引用
// 4. 结构体不能继承其他结构体或类,但可以实现接口
}
}
/// <summary>
/// 英雄结构体
/// </summary>
struct Hero
{
// 成员
// 成员字段(变量)
// 访问修饰符
// 1. public: 公共的,可以被外部访问
// 2. private: 私有的,只能在结构体内部访问
public string Name; // 默认值是 null
public int Attack; // 成员存在默认值,数值类型(int, float, double)默认值是 0
public int Hp;
// 默认有一个无参构造函数
// 构造函数
public Hero(string Name, int attack, int hp)
{
// 同名变量的就近原则,就近:定义的位置
Name = Name;
this.Name = Name; // this 关键字指代当前结构体实例
Attack = attack;
Hp = hp;
}
public Hero(string name,int attack, int hp,int attackBuff)
{
Name = name;
Hp = hp;
Attack = attack + attackBuff; // 攻击力加上攻击增益
}
// 成员函数
public void Show()
{
Debug.Log($"英雄: {Name}, 攻击力: {Attack}, 生命值: {Hp}");
}
}
/// <summary>
/// 英雄类
/// </summary>
public class HeroClass
{
public string Name;
public int Attack;
public HeroClass(string name, int attack)
{
Name = name;
Attack = attack;
}
public void Show()
{
Debug.Log($"英雄: {Name}, 攻击力: {Attack}");
}
}