C#(5):数据类型、变量与对象

强弱类型的区别:变量受类型约束的强弱程度。

弱类型变量比较灵活,但是后期容易扰乱逻辑。

c#不推荐使用指针

一个程序从硬盘加载到内存,就变成了进程。

数据类型构成了c#术语类型系统,可以分为引用类型和值类型

静态变量:变量名表示变量值在内存中的存储位置。并不是变量值装在变量名中。

实例变量:静态成员变量隶属于类,而不是类的实例。张三的身高属性、搬砖方法隶属于人的类,而不是实例化的张三。

数组元素:声明数组实例,并且确定数组数量以确定数组字节总长度。

值参数:类型加变量名

引用参数变量:ref 值参数

输出参数变量:out 值参数

局部变量:在函数体中声明的变量。

修饰符组合:可选,public、private。

初始化器:可选,给声明变量一个初始值。


变量是以变量名所对应的内存地址为起点,以其数据类型所要求的存储空间为长度的一块内存区域。

比如byte类型,范围是0-255,表明byte类型的变量需要一个字节。刚好一个内存地址存放八位数字11111111二进制的255到000000000二进制的0。

比如sbyte,范围是-127-128,拿出最高位当作符号位。然后计算机选择内存起始点,分配一个字节存储数据(8个二进制位表示),而又有一位被当作符号位,正数只能表达到128。表达负数时按位取反再加1,少一位只能表达到127。

比如ushort,占用内存十六bit,是留给二进制位。0-65535。


在C#里,变量可以分为两大类:值类型和引用类型。它们之间的主要区别在于它们在内存中的存储方式。

对于值类型,其变量直接存储实际的数据。这种类型的变量在声明时会在栈上分配相应的内存空间来直接存储值。例如int, bool, double和struct等。

对于引用类型,它们的变量并不直接存储实际的数据。相反,它们存储的是实际数据所在内存的地址(这就是为什么它们被称为"引用"类型)。引用类型的变量在创建时,在堆上为存储实际的数据(实例)分配内存,然后在栈上为存储这块堆内存的地址分配内存。这意味着引用类型的变量实际上是存储在栈上的,它存储的是一个引用(地址),这个引用指向存储数据的堆内存。

让我们来理解一下引用类型变量引用类型的实例的区别:

- 引用类型变量(stu、stu2):这是存在于栈上的变量,它存储的是引用类型实例在堆上的地址。
  
- 引用类型实例(student):这是存在于堆上的内存块,它包含实际的数据。

在C#中,类(class)和接口(interface)是典型的引用类型。这意味着当你创建一个类的实例时,实例本身(即数据)是存在堆上的,而变量(存放堆内存地址的)则存在栈上。


局部变量在栈上分配内存,实例分配在堆上,根据实例的变量属性动态分配大小。

类的变量在内存分配好后,内存块默认全复制0,初始值为0。常规变量必须要初始化否则不会有初始值。

const:类型修饰符,表示变量值不能更改。


装箱:装箱是指将值类型转换为引用类型的过程。在.Net中,所有的类型都派生自System.Object类型,所以可以通过装箱过程把值类型转换为System.Object类型或者对应的接口类型。

例如,假设我们有一个值类型int,我们可以把它装箱为object类型:

```
int val = 1;
object obj = val;  // 这里就发生了装箱操作
```

在这个例子中,我们创建了一个int 类型的变量 val,然后把它装箱成一个object类型的变量 obj。这样,obj就可以作为一个object类型的引用,在堆内存中存储一个int类型的值。

装箱操作在一定程度上增加了数据的灵活性,但是会引入额外的性能开销,因此需要谨慎使用。


在C#中,拆箱(Unboxing)是指将对象类型(object type)转换回值类型(value type)的操作。在C#中,所有的类型都从一个共通的系统类型System.Object派生。这就意味着我们可以将任何类型的变量分配给这个基类型。这就是装箱操作。相反的,当我们有一个引用类型并且我们需要将它转换回值类型的时候,就需要执行一个拆箱操作。

以下是一个简单的例子:

```csharp
    object MyObject = 30;  // 装箱
    int MyInt = (int)MyObject;  // 拆箱
```

在这个例子中,一个int类型的值被装箱为一个object类型,然后再被拆箱回int类型。装箱和拆箱在内部涉及到系统资源的分配和回收,所以它会影响性能。因此,最好在编程时避免频繁地装箱和拆箱。

posted @ 2023-09-15 16:23  HY10-SALTEST-FISH  阅读(69)  评论(0编辑  收藏  举报