C#学习笔记--复杂数据类型、函数和结构体

这篇具有很好参考价值的文章主要介绍了C#学习笔记--复杂数据类型、函数和结构体。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C#基础

复杂数据类型

特点:多个数据变量地一个集合体,可以自己命名

种类:枚举、数组和结构体

  • 枚举:整型常量的集合
  • 数组:任意变量类型的顺序存储的数据集合
  • 结构体:任意变量类型的数据组合成的数据块

枚举

枚举可以方便表示对象的各种状态,本质还是一种变量。

例如我们可以用枚举来表示怪物的种类、玩家的动作状态(静止、战斗、受伤......)

枚举的声明:

enum E_MonsterType//命名E_XXX
{
     Normal,//0
     Boss,//1 自动根据上一个数值顺延
}
enum E_PlayerType
{ 
     Main,
     Other,
}

枚举类型的使用:

//自定义的枚举类型  变量名 = 默认值;(自定义的枚举类型.枚举项)
E_PlayerType playerType = E_PlayerType.Other;

if( playerType == E_PlayerType.Main )
{
    Console.WriteLine("主玩家逻辑");
}
else if(playerType == E_PlayerType.Other)
{
    Console.WriteLine("其它玩家逻辑");
}
//枚举也常常与switch语句做配合

 //枚举和switch是天生一对
E_MonsterType monsterType = E_MonsterType.Boss;
switch (monsterType)
{
    case E_MonsterType.Normal:
        Console.WriteLine("普通怪物逻辑");
        break;
    case E_MonsterType.Boss:
        Console.WriteLine("Boss逻辑");
        break;
    default:
        break;
}

枚举类型转换:

  • 枚举与int互转:
int i=(int) playerType;
playerType=0;
  • 枚举与string互转:
playerType=(E_PlayerType)Enum.Paese(typeof(E_PlayerType),"other");
string str=playerType.ToSring();

数组

数组是存储同一种特定变量类型的有序数据集合,内存上的连续存储。

一维数组

//数组声明
int[] arr1;//未分配内存地址
int[] arr2=new int[5];//元素默认值0
int[] arr3=new int[5]{1,2,3,4,5};
int[] arr4=new int[]{1,2,3};
int[] arr5={1,2,3,4,5,6};

//数组的使用
arr2.Length;//长度
arr2[0];//获取数组中的元素
arr2[2]=99;//修改内容
//数组的遍历
for(int i=0;i<arr2.Length;i++)
{
    //遍历
     Console.WriteLine(arr2[i]);
}

//数组的自定义扩容
//声明新的大容量数组,把旧有的进行复制转移
int[] array2 = new int[6];
//搬家
for (int i = 0; i < array.Length; i++)
{
    array2[i] = array[i];
}
array = array2;

//自定义实现数组的删除元素
int[] array3 = new int[5];
//搬家 转移
for (int i = 0; i < array3.Length; i++)
{
    array3[i] = array[i];
}
array = array3;


//查找数组中元素
//只有遍历数组 找到合适的则终止遍历
int a = 3;
for (int i = 0; i < array.Length; i++)
{
    if( a == array[i] )
    {
        Console.WriteLine("和a相等的元素在{0}索引位置", i);
        break;
    }
}

多维数组(二维数组)

//二维数组
//声明
int[,] arr;
int[,] arr2=new int[3,4];
int[,] arr3=new int[3,4]{{0,1,2,3},//给元素内容  告诉维度 元素个数
                         {0,1,2,3},
                         {0,1,2,3}};
int[,] arr4=new int[,]{{0,1,2,3},//给元素内容 告诉维度
                         {0,1,2,3},
                         {0,1,2,3}};
int[,] arr5={{0,1,2,3},    //直接给元素内容
             {0,1,2,3},
             {0,1,2,3}};

//使用
//获取长度
arr3.GetLength(0);//行的长度
arr3.GetLength(1);//列的长度

//获取元素
arr3[1,1];//第一行第一列的元素
//遍历二维数组
for(int i=0;i<arr3.GetLength(0);i++)
{
    for(int j=0;j<arr3.GetLength(1);j++)
    {
        //访问 具体元素
    }
}
//增加数组元素
//思想:新建一个大容量的数组,将小的数组元素复制到大的数组中
//最后修改小的数组索引指向大的数组 实现“数组扩容”
//删除数组元素(同增加)
//查找数组中的元素(遍历比对)

交错数组

交错数组区别于多维数组,是数组的数组,一维数组元素也是数组,且长度不必完全相同。

//交错数组
//声明
int [][] arr1;
int [][] arr2=new int[3][];//不可以规定列的长度
int [][] arr3=new int[3][]{
    new int[] {1,2,3,4},
    new int[] {1,2,3},
    new int[] {1}
};//体会数组的数组的含义!
int [][] arr4=new int[][]{
    new int[] {1,2,3,4},
    new int[] {1,2,3},
    new int[] {1}
};

int [][] arr5={//也可以直接赋值
    new int[] {1,2,3,4},
    new int[] {1,2,3},
    new int[] {1}
};

//数组的使用
//长度
arr3.GetLength(0);//行数
arr3[0].Length;//第0行的长度

//获取元素
arr3[0][2];
//遍历
for(int i=0;i<arr3.GetLength(0);i++)
{
    for(int j=0;j<arr3[i].Legth;j++)
    {
        //访问元素
        Console.WriteLine(arr3[i][j]);
    }
}

值类型和引用类型

值类型的数值存储在(系统分配,自动回收GC,小而快)中、引用类型的存储在(大而慢,需手动分配与回收)中,栈中只存储其指针;

值类型在赋值时候将数值拷贝,而引用赋值修改引用指向的内存位置。

值类型:(14+2(枚举、结构体))

  • 无符号整型:byte ushort uint ulong
  • 有符号整型:sbyte short int long
  • 浮点数: float double decimal
  • 特殊类型:bool char
  • 结构体
  • 枚举:enum

引用类型:(5种)

string 、数组、类、接口、委托

函数

函数本质是封装的代码块,提升代码的复用率,抽象出具体的执行过程。

函数只能存在 structclass

//函数出现在stuct与class中
//函数种类
//1 无参数 无返回值
void sayHellow()
{
    Console.WriteLine("Hello World");
}
//2 有参数 无返回值
void sayHellow(string name)
{
    Console.WriteLine("Hello,"+name);
}
//3 有参数 有返回值
int Add(int a,int b)
{
    return a+b;
}
//4 无参数 有返回值
string getMyName()
{
    return "TonyChang";
}

ref 和 out

使用其可以解决在函数内部改变函数外部的变量的数值的问题。

(本质是传参数过程中传的是数值或引用是否完全绑定到同一个数值/内存空间中)

//ref的使用
using System;
namespace CSharpLearn1
{
    class Program
    {
        static void ChangeValue(int value)
        {
            value = 3;
        }
        static void ChangeArrayValue(int[] arr) 
        {
            arr[0] = 33;
        }
        static void ChangeArray(int[] arr)
        {
            arr = new int[] {666,777,888,999 };
        }
        static void ChangeValueRef(ref int value)
        {
            value = 3;
        }
        static void ChangeArrayValueRef(ref int[] arr)
        {
            arr[0] = 33;
        }
        static void ChangeArrayRef( ref int[] arr)
        {
            arr = new int[] { 666, 777, 888, 999 };
        }
        static void Main(string[] args)
        {
            
            int a1 = 1;
            Console.WriteLine("a1原数值{0}", a1);
            ChangeValue(a1);
            Console.WriteLine("调用ChangValue函数之后a1的数值{0}", a1);//未改变数值
            ChangeValueRef(ref a1);
            Console.WriteLine("a1调用ChangValueRef函数之后a1的数值{0}", a1);//改变数值
            Console.WriteLine("********************************");

            int[] arr1 = { 100, 200, 300 };
            Console.WriteLine("arr1[0]原数值{0}", arr1[0]);
            ChangeArrayValue(arr1);
            Console.WriteLine("调用ChangArrayValue函数之后arr1[0]的数值{0}", arr1[0]);//改变数值
            Console.WriteLine("********************************");

            int[] arr2 = { 100, 200, 300 };
            Console.WriteLine("arr2[0]原数值{0}", arr2[0]);
            ChangeArray(arr2);
            Console.WriteLine("调用ChangArrayValue函数之后arr2[0]的数值{0}", arr2[0]);//未变数值
            ChangeArrayRef(ref arr2);
            Console.WriteLine("调用ChangArrayValueRef函数之后arr2的数值{0}", arr2[0]);//改变数值
            Console.WriteLine("********************************");

            int[] arr11 = { 100, 200, 300 };
            Console.WriteLine("arr11[0]原数值{0}", arr11[0]);//改变数值
            ChangeArrayValueRef(ref arr11);
            Console.WriteLine("调用ChangArrayValueRef函数之后arr[0]的数值{0}", arr11[0]);//改变数值
            Console.WriteLine("********************************");
        }
    }
}

C#学习笔记--复杂数据类型、函数和结构体

Out

//添加两个OUt修饰参数的函数   
static void ChangeValueOut(out int value)
    {
        value = 3;
    }
    static void ChangeArrayOut(out int[] arr)
    {
        arr = new int[] { 666, 777, 888, 999 };
    }
//添加到Main函数中

 int a1 = 1;
            Console.WriteLine("a1原数值{0}", a1);
            ChangeValue(a1);
            Console.WriteLine("调用ChangValue函数之后a1的数值{0}", a1);//未改变数值
            ChangeValueOut(out a1);
            Console.WriteLine("a1调用ChangValueOut函数之后a1的数值{0}", a1);//改变数值
            Console.WriteLine("********************************");
            int[] arr1 = { 100, 200, 300 };
            Console.WriteLine("arr1[0]原数值{0}", arr1[0]);
            ChangeArray(arr1);
            Console.WriteLine("调用ChangArray函数之后arr1[0]的数值{0}", arr1[0]);//未改变数值
            ChangeArrayOut(out arr1);
            Console.WriteLine("调用ChangArrayOut函数之后arr1[0]的数值{0}", arr1[0]);//改变数值

C#学习笔记--复杂数据类型、函数和结构体

区别:

  1. ref传入的变量必须初始化 out不必
  2. out传入的变量必须在内部进行赋值 ref不必

理解:ref在传入时候已经有初始值,所以在内部可以不作修改,

​ out在传入时候可能未有初始值,所以要保证有效,在内部必须进行赋值。

函数的变长参数关键字 ---params

  1. 其后只能跟数组
  2. 数组类型可以为任意类型
  3. 函数参数列表中只能出现一个params,并且修饰的参数只能在末尾出现
//函数变长参数关键字 params后必须为数组
//求n个int的和
int Sum(params int[] arr)
{
    int sum=0;
    for(int i=0;i<arr.Length;i++)
    {
        sum+=arr[i];
    }
    return sum;
}
void Chat(string name,params string[] things)
{
    //函数体...
}

函数的参数默认值

函数参数列表中可以有多个参数,有默认值的参数一定在普通参数的后面

void Speak(string thing="我没什么可说的了")
{
    Console.WriteLine(thing);
}
//调用
Speak();
Speak("我想说,,,,");

函数重载:

在同一语句块中,函数名字相同,函数的参数列表不同(参数类型不同或参数的个数不同,二者均相同则参数顺序不同)

//函数重载
//函数的参数数量不同 
int Sum(int a,int b)
{
    return a+b;
}
int Sum(int a,int b,int c)
{
    return a+b+c;
}
// 参数 数量相同 类型不同
float Sum(int a,int b)
{
    return a+b;
}
float Sum(float f1,float f2)
{
    return f1+f2;
}
//参数 数量相同 类型相同 顺序不同
float Sum(float f,int i)
{
    return f+i;
}
float Sum(int i,float f)
{
    return f+i;
}
//ref 和 out 改变参数类型 与普通的函数构成重载
//ref 和out 算作一类 自身不可互相构成重载
int Sum(int a,int b)
{
    return a+b;
}
int Sum(ref int a,int b)
{
    return a+b;
}
//params 可以作为重载
//但是 参数默认值不可构成重载

递归函数

函数自己调用自己,递归有递归基与结束调用的条件.

//递归打印0-10
void Fun(int a)
{
    if(a>10)
        return;
    Console.WriteLine(a);
    a++;
    Fun(a);
}
//递归----求某一数的阶乘
int getFactorial(int a)
{
    //结束条件
    if(a==1)
        return 1;
    //递归基
    return a*getFactorial(a-1);
}
//递归----求1!+2!+3!+···+10!
int getFactorialSum(int num)
{
    if(num==1)
        return 1;
    return getFactorial(num)+getFactorial(num-1);
}
//递归---
//一根竹竿长100m,每天砍掉一半,求第十天的长度是多少?
void getLong(float length,int day=0)
{
    length/=2;
    if(day==10)
    {
        Console.WriteLine("第十天砍后的竹子长度为{0}米",length);
    }
    ++day;
    getLong(length,day);
}
//---递归打印1-200
//递归+短路
bool Fun5(int num)
{
    Console.WriteLine(num);
    return num==200||Fun5(num+1);//第一个为条件真 便会短路
}

结构体

结构体是数据与方法的集合,在namespace

命名规则:帕斯卡命名法(首字母均大写)

构造函数:

  1. 无返回值
  2. 必须与结构体名字相同
  3. 必须有参数
  4. 如有构造函数,必须把所有的变量进行赋值
//结构体
struct Student
{
    //不可以包含自身类型的结构体--Student  s; 报错!
    //姓名:
    public string name;
    //年龄
    public int age;//数值变量不可以直接初始化
    public bool sex;
    //构造函数(默认有一个无参构造函数,若有构造函数则默认的构造函数不会失效,这点与类不同)
    //对变量进行初始化
    public Student(string name,int age,bool sex)
    {
        this.name=name;
        this.age=age;
        this.sex=sex;
    }
    //方法
    public void Speak()
    {
        Console.WriteLine("你好");
    }
}

//结构体的使用
Student s1;
s1.name="Tony";
s1.age=18;
s1.sex=true;
s1.Speak();

访问修饰符

  1. public
  2. private(默认不写算私有)
  3. protect 继承的可以访问
  4. internal - 内部的 只有在同一个程序集的文件中,内部类型或者是成员才可以访问

既然都看到这里了,那就给个👍吧!
小小一赞,给作者的莫大的鼓励!
关注我,我会每天更新C#学习笔记,从入门到进阶,一起来学习啊!!!文章来源地址https://www.toymoban.com/news/detail-711654.html

到了这里,关于C#学习笔记--复杂数据类型、函数和结构体的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C#学习笔记】引用类型(1)

    引用类型的变量存储对其数据(对象)的引用,而值类型的变量直接包含其数据。 对于引用类型,两种变量可引用同一对象;因此,对一个变量执行的操作会影响另一个变量所引用的对象。 对于值类型,每个变量都具有其自己的数据副本,对一个变量执行的操作不会影响另

    2024年02月14日
    浏览(37)
  • 【C#学习笔记】引用类型(2)

    支持 .NET 类层次结构中的所有类,并为派生类提供低级别服务。 这是所有 .NET 类的最终基类;它是类型层次结构的根。 简单来说,它是万能的,它是所有类型的父类。因为.NET 中的所有类都派生自 Object,因此 Object 类中定义的每个方法都可用于系统中的所有对象。 在 Object

    2024年02月14日
    浏览(40)
  • 掌握Go语言:Go语言类型转换,解锁高级用法,轻松驾驭复杂数据结构(30)

    在Go语言中,类型转换不仅仅局限于简单的基本类型之间的转换,还可以涉及到自定义类型、接口类型、指针类型等的转换。以下是Go语言类型转换的高级用法详解: Go语言类型转换的高级用法 1. 自定义类型之间的转换 在Go语言中,可以使用类型别名或自定义类型来创建新的

    2024年04月09日
    浏览(57)
  • C#学习笔记--变量类型的转换

    转换原则 同类型的大的可以装小的,小类型的装大的就需要强制转换。 隐式转换: 同种类型的转换: 不同类型的转换: char类型可以隐式转换成数值型,根据对应的ASCII码来进行转换。 无符号的无法隐式存储有符号的,而有符号的可以存储无符号的。 显示转换 括号强转(注

    2024年02月08日
    浏览(36)
  • C# 学习笔记2-控制流与类型转换

    关于变量的简单操作 判断 循环 类型转换 异常处理 检查数字类型的溢出 一元运算符 Unary operators x++ , ++x , x-- , --x 。 这些运算符同 C++。 postfix operator 后置运算符 还有 typeof(int) , sizeof(int) 。 二元运算符 Binary arithmetic operators 无非是: + 、 - 、 * 、 / 、 % modulus 模 remaind

    2024年02月02日
    浏览(26)
  • 学习数据结构:算法的时间复杂度和空间复杂度

    衡量一个算法的好坏,一般是从时间和空间两个维度来衡量的,即时间复杂度和空间复杂度。 时间复杂度主要衡量一个算法的运行快慢,而空间复杂度主要衡量一个算法运行所需要的额外空间。 算法的时间复杂度 算法中的基本操作的执行次数,为算法的时间复杂度。 算法的

    2024年04月11日
    浏览(33)
  • 数据结构学习分享之复杂度讲解

    在我们学习完C语言的所有内容后,现在就可以开始我们的数据结构的学习,如果有读者也想走C/C++研发方向,可以跟着我一起往后学. 本篇文章将收于专栏 数据结构学习分享, 会持续更新内容. 数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定

    2024年02月01日
    浏览(23)
  • 数据结构学习之路--算法的时间复杂度与空间复杂度(精讲)

         嗨嗨大家!本期带来的内容是:算法的时间复杂度与空间复杂度。 目录 前言 一、算法效率 算法效率的衡量标准 二、时间复杂度 1 时间复杂度的定义 2 求解时间复杂度的步骤 2.1 找出算法中的基本语句:  2.2计算基本语句执行次数的数量级: 2.3大O阶的渐进表示法:

    2024年04月09日
    浏览(50)
  • 深入学习与探索:高级数据结构与复杂算法

    🎉欢迎来到数据结构学习专栏~深入学习与探索:高级数据结构与复杂算法 ☆* o(≧▽≦)o *☆嗨~我是IT·陈寒🍹 ✨博客主页:IT·陈寒的博客 🎈该系列文章专栏:数据结构学习 📜其他专栏:Java学习路线 Java面试技巧 Java实战项目 AIGC人工智能 数据结构学习 🍹文章作者技术和

    2024年02月09日
    浏览(36)
  • C#学习笔记3-函数与单元测试

    现在开始参考书籍变为:《C# 12 and .NET 8 – Modern Cross-Platform Development.Mark Price》 Writing, Debugging, and Testing Functions 写函数 Debug 运行时 logging 单元测试 一个有着 XML 注释的函数 这里直接举一个例子: Numbers that are used to count are called cardinal numbers(基数), for example, 1, 2, and 3. Wher

    2024年01月18日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包