首页 > 编程语言 >C# 之 结构体详解

C# 之 结构体详解

时间:2023-03-17 09:02:31浏览次数:57  
标签:Console name WriteLine C# age 详解 Student 结构

C# 之 结构体详解
https://blog.csdn.net/Czhenya/article/details/106755779

C# 之 结构体详解

一.结构体的定义

概念:C#的结构体类型(或称为结构)是用户自定义类型的一种, 它为用户将实际应用中数据类型不同,但互相联系的数据看作 一个整体提供了类型支持。

结构体是值类型的数据类型,可定义在任意命名空间或类中,使用时在其定义域内使用。

定义形式为:

public struct Student//结构体类型名
{
	 //各种成员...:
	 //成员定义格式为: 访问修饰符 成员类型 成员名称
	 //例:
	 public string name;
	 int age;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

如果在定义结构体时,某个数据成员之前没有public访问修饰符,则结构体类型变量不能访问这个数据成员。(如上面结构体的age变量是不能被访问的)

结构体类型的定义是借助struct关键字向编译器声明了一种新的数据类型;对于该数据类型并没有分配相应的存储空间,因此不能直接对结构体中的变量成员进行访问,赋值等操作;只能在其被实例化之后才可以对其进行操作。
示例
结构体的成员可以是基础数据成员,也可以是结构体类型成员(不能是本结构体)。

结构是密封的、不能继承的。

分配结构比分配类的实例需要更少的消耗,所以对于仅由几个基础类型组成的新类型,优先推荐使用结构。


二.结构体的初始化

在定义结构体变量(或者说是实例化结构体)时,系统会根据结构体类型的定义为其分配相应的存储空间,此时就可以对结构体中的成员进行赋值,访问等操作了。

1.实例构造函数

若调用无参数构造进行初始化,则所有变量都会被设置为该类型的默认值。

结构体预定义的无参构造函数是不允许被重新定义的,并且他会一直存在。
不支持无参构造

定义带参数的构造函数时,需要将所有字段进行初始化

全部初始化
示例代码:

class Programma
{
    static void Main(string[] args)
    {
      	Student s1 = new Student();            
        Console.WriteLine(s1.name); //输出: (空)
        Console.WriteLine(s1.age);  //输出:0
        s1.name = "CZY";
        s1.age = 11;
        Console.WriteLine(s1.name); //输出:CZY
        Console.WriteLine(s1.age);  //输出:11
        Student s2 = new Student("Czhenya", 5);
        Console.WriteLine(s2.name); //输出:Czhenya
        Console.WriteLine(s2.age);  //输出:5
	}
	struct Student
    {
        public string name;// = "Czhenya";
        public int age;
        public Student(string name,int age)
        {
             this.name = name;
             this.age = age;
        }
     }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

2.静态构造函数

静态构造函数不能有参数
静态构造必须无参数
静态构造函数不能有访问修饰符
静态构造不支持访问修饰符
静态构造函数不能有访问修饰符,它会在使用带参构造函数进行初始化时被自动调用访问静态数据成员时调用

class Programma
{
    static void Main(string[] args)
    {
    	// 实例化时自动调用静态函数
      	//Student s3 = new Student("Czhenya", 5); 
       	// 访问静态成员时会自动调用	
		//Console.WriteLine(Student.id);
		// 给静态成员赋值时会自动调用
        Student.id = 1;
        Console.WriteLine(Student.id);
	}
	struct Student
    {
        public string name;// = "Czhenya";
        public int age;
        public static int id;
        public Student(string name,int age)
        {
             this.name = name;
             this.age = age;
        }
        static Student()
        {
             Console.WriteLine("静态构造函数被自动调用了...");
        }
     }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

上面测试代码注释全部打开时,可以发现静态构造只会被调用一次


三.结构体的使用

1.赋值操作

Student s4 = new Student("Czhenya", 5); 
Student s5 = s4;
  • 1
  • 2

结构体对象赋值时,本质上是把一个对象内存空间中的全体成员赋值到另一个对象存储空间中。

如果结构体类型中包括大量的数据成员时,结构体对象的赋值会耗费大量时间,所以一般情况下我们通常情况下不会这样写。

2.作为方法参数和返回值

结构体作为方法的值参数时将整个结构体深层复制一份到方法的调用空间里,在方法体内对作为值参数传递进来的结构体进行修改时,不会影响到方法体外作为实参的结构体。因此,结构体作为值参数进行传递时花销很大,我们在使用时,通常传递多个所需要的参数,而不是将整个结构体传进去。

class Programma
{
    static void Main(string[] args)
    {
 		Student s6 = new Student("Czhenya", 5);
		Show(s6); 
        Show(s6.name, s6.age);
        Student s7 = Show();
        Console.WriteLine(s7.name);
        Console.WriteLine(s7.age);
    }
    static void Show(Student stu)
    {
        Console.WriteLine("这是使用结构体作为参数的Show方法:" + stu.name + stu.age);
    }
    static void Show(string name, int age)
    {
        Console.WriteLine("这是多个参数的Show方法..." + name + age);
    }
    static Student Show()
    {
        Console.WriteLine("这是结构体作为返回值的Show方法...");
        return new Student("Czhenya", 5);
    }
	//还上面代码中的Student结构体
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

输出

结构体不仅可以作为方法的形式参数,也可使用 refout作为关键字当做方法的实际参数。

标签:Console,name,WriteLine,C#,age,详解,Student,结构
From: https://www.cnblogs.com/sunny3158/p/17225343.html

相关文章

  • ArrayList 和 Vector 的区别是什么?
    同步性Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用Array......
  • Windows docker desktop 时区设置
    必须设置时区,否则查询出来的时间会有问题:(本人安装了mysql,但是修改mysql的配置没起作用) 进入容器执行:cp/usr/share/zoneinfo/Asia/Shanghai/etc/localtime&&echo‘......
  • HTML中的表格的基本结构与常用属性
    1、表格的基本结构首先看看图下<table>标签的布局                                    ......
  • C++11lambda表达式精讲
    lambda表达式的概念和基本用法lambda表达式定义了一个匿名函数,并且可以捕获一定范围内的变量。lambda表达式的语法形式可简单归纳如下:[capture](params)opt->......
  • Acwing 291. 蒙德里安的梦想
     状态压缩DP当把所有横向格子放完后,纵向方格的排放方案只有一种。因此整个划分方案数与横着摆放方格的方案数相同。f[i,j]表示,目前摆放第i列,j是二进制数(状态是整数,看......
  • 滴水 316 复习 结构体
    结构体1.为什么需要结构体需要一个东西来存储非常多的东西。比如生命蓝量坐标2.结构体定义赋值structMyStruct{inta;intb;intc;};intmain(){MyStruct......
  • 盘点一个Excel多条件求和的问题
    大家好,我是皮皮。一、前言前几天在Python最强白银交流群【维哥】问了一个Excel处理的问题,这里拿出来给大家分享下。下图是他的数据:二、实现过程这个问题确看上去是E......
  • Microsoft.NET和Windows应用程序调试 读书笔记
    WhyIsn'tThereaChapteron.NETDebuggers?Youmightbewonderingwhythereisn'tacorrespondingchapterinthisbookonhowMicrosoft.NETdebuggerswork.O......
  • 【leetcode】226.翻转二叉树
    翻转二叉树leetcode题目传送门题目描述思路按顺序依次交换二叉树的左右节点实现交换左右节点,递归遍历publicclassTreeNode{publicintval;......
  • 黑马阶段三 C++篇 02day
    2day1.引用是什么:给变量空间取别名intmain(){inta=0;int&b=a;b=100;cout<<a<<endl;return0;}2.引用的注意使用引用类型可以像指针那样访问只......