7.值类型和引用类型-使用和存储上的区别
7.1 知识点
变量类型复习
无符号整形
byte by = 1; ushort us = 1; uint ui = 1; ulong ul = 1;
有符号整形
sbyte sby = 1; short s = 1; int i = 1; long l = 1;
浮点数
float f = 1f; double d = 1.1; decimal de = 1.1m;
特殊类型
bool bo = true; char c = 'A'; string str = "strs";
复杂数据类型
- enum(枚举)
- 数组(一维,二维,交错)
值类型和引用类型的分类
- 引用类型: string, 数组, 类(未学习)
- 值类型: 其它、结构体(未学习)
值和引用的区别
使用上的区别
//值类型
int a = 10;
//引用类型
int[] arr = new int[] { 1, 2, 3, 4 };
//声明了一个b让其等于之前的a
int b = a;
//声明了一个arr2让其等于之前的arr
int[] arr2 = arr;
Console.WriteLine("赋值了b和arr2[0]之后");
Console.WriteLine("a={0}, b={1}", a, b);//a=10, b=10
Console.WriteLine("arr[0]={0}, arr2[0]={1}", arr[0], arr2[0]);//arr[0]=1, arr2[0]=1
b = 20;
arr2[0] = 5;
Console.WriteLine("修改了b和arr2[0]之后");
Console.WriteLine("a={0}, b={1}", a, b);//a=10, b=20
Console.WriteLine("arr[0]={0}, arr2[0]={1}", arr[0], arr2[0]); //arr[0] = 5, arr2[0] = 5
总结
值类型在相互赋值时,把内容拷贝给了对方,它变我不变。引用类型的相互赋值是让两者指向同一个值(指向同一内存地址),它变我也变。
为什么有以上区别
值类型和引用类型存储在的内存区域是不同的,存储方式也是不同的:
- 值类型存储在栈空间:系统分配,自动回收,小而快。
- 引用类型存储在堆空间:手动申请和释放,大而慢。
New了就是开了新房间,和之前的没有关系,所以arr不会有任何变化。
值类型和引用类型的内存图示
7.2 知识点代码
using System;
namespace Lesson05_值类型和引用类型存储上的区别
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("值类型和引用类型存储上的区别");
#region 知识点一 变量类型的复习
//无符号整形
byte by = 1;
ushort us = 1;
uint ui = 1;
ulong ul = 1;
//有符号整形
sbyte sby = 1;
short s = 1;
int i = 1;
long l = 1;
//浮点数
float f = 1f;
double d = 1.1;
decimal de = 1.1m;
//特殊类型
bool bo = true;
char c = 'A';
string str = "strs";
//复杂数据类型
// enum 枚举
// 数组 (一维,二维,交错)
//可以把以上 学过的 变量类型 分成 值类型和引用类型
//引用类型: string, 数组, 类(未学习)
//值类型: 其它、结构体(未学习)
#endregion
#region 知识点二 值类型和引用类型的区别
//1.使用上的区别
//值类型
int a = 10;
//引用类型
int[] arr = new int[] { 1, 2, 3, 4 };
//声明了一个b让其等于之前的a
int b = a;
//声明了一个arr2让其等于之前的arr
int[] arr2 = arr;
Console.WriteLine("赋值了b和arr2[0]之后");
Console.WriteLine("a={0}, b={1}", a, b);//a=10, b=10
Console.WriteLine("arr[0]={0}, arr2[0]={1}", arr[0], arr2[0]);//arr[0]=1, arr2[0]=1
b = 20;
arr2[0] = 5;
Console.WriteLine("修改了b和arr2[0]之后");
Console.WriteLine("a={0}, b={1}", a, b);//a=10, b=20
Console.WriteLine("arr[0]={0}, arr2[0]={1}", arr[0], arr2[0]); //arr[0] = 5, arr2[0] = 5
//值类型 在相互赋值时 把内容拷贝给了对方 它变我不变
//引用类型的相互赋值 是 让两者指向同一个值(指向同一内存地址) 它变我也变
//2.为什么有以上区别
//值类型 和 引用类型 存储在的 内存区域 是不同的 存储方式是不同的
//所以就造成了 他们在使用上的区别
// 值类型存储在 栈空间 —— 系统分配,自动回收,小而快
// 引用类型 存储在 堆空间 —— 手动申请和释放,大而慢
//new 了 就是开了新房间 和之前的 没有什么关系了 所以 arr不会有任何变化
arr2 = new int[] { 99,3,2,1};
Console.WriteLine("arr[0]={0}, arr2[0]={1}", arr[0], arr2[0]);//arr[0] = 5, arr2[0] = 99
#endregion
}
}
}
7.3 练习题
int a = 10; int b = a; b = 20; Console.WriteLine(a);请问打印结果为多少?
答: 10
解释:
int
是值类型,将a
的值(10)复制给b
时,是将实际的值拷贝,而不是引用。因此,b = 20;
不会影响到a
的值。
int[] a = new int[]{10}; int[] b = a; b[0] = 20; Console.WriteLine(a[0]);请问打印结果为多少?
答: 20
解释:
int[]
是引用类型,a
和b
指向同一块内存地址。修改b[0]
的值会影响到a[0]
,因为它们指向相同的数组。
string str = “123”; string str2 = str; str2 = “321”; Console.WriteLine(str);请问打印结果为多少?
答: 123
解释:
string
是一个特殊的引用类型,但它是不可变的。在这个例子中,str
和str2
最初都指向 “123” 这个字符串,但在str2 = "321";
时,str
不受影响,因为字符串是不可变的,新的字符串 “321” 会被分配到一个新的内存地址,而str2
将指向这个新的地址。
7.4 练习题代码
using System;
namespace Lesson05_练习题
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("值类型和引用类型存储上的区别练习题");
#region 练习题一
int a = 10;
int b = a;
b = 20;
Console.WriteLine(a);
//请问打印结果为多少?
//10
//值类型:它变我不变
//值类型是存在栈上
#endregion
#region 练习题二
int[] a2 = new int[] { 10 };
int[] b2 = a2;
b2[0] = 20;
Console.WriteLine(a2[0]);
//请问打印结果为多少?
//20
//引用类型:它变我也变
//引用类型存在堆上
#endregion
#region 练习题三
string str = "123";
string str2 = str;
str2 = "321";
Console.WriteLine(str);
//请问打印结果为多少?
//123
//string是一个特殊的引用类型,它不遵循它变我也变
#endregion
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com