值类型:
声明在栈中,数据存储在栈中
引用类型:
声明在栈中,数据存储在堆中,栈中存储该数据的引用
理解:
1、因为方法执行在栈中,所以在方法中声明的变量都在栈中
2、因为值类型直接存储数据,所以数据存储在栈中
3、又因为引用类型存储数据的引用,所以数据在堆中,栈中存储数据的内存地址
static void Main()
{
int num01 = 1, num02 = 1;
bool r1 = num01 == num02;//true,因为值类型存储的是数据,所以比较的时数据
int[] arr01 = new int[] { 1 }, arr02 = new int[] { 1 };
bool r2 = arr01 == arr02;//false,因为引用类型存储的时数据的引用,所以比较的是存储的引用
bool r3 = arr01[0]== arr02[0];//ture
}
static void Main()
{
// 值类型 引用类型
//int bool char string Array
//a在栈中 1在栈中
int a = 1;
int b = a;
a = 2;
Console.WriteLine(b);//?
//arr在栈中存储数组对象的引用(内存地址) 1在堆中
int[] arr = new int[] { 1 };
int[] arr2 = arr;
//arr2[0] = 2;//修改的是堆中的数据
arr = new int[]{2};//修改的是栈中存储的引用
Console.WriteLine(arr2[0]);//?
string s1 = "男";
string s2 = s1;
s1 = "女";//修改的是栈中存储的引用
//s1[0]='女';//堆中的文字 不能修改
Console.WriteLine(s2);//?
// o1 在栈中 数据1 在堆中
object o1 = 1;
object o2 = o1;//o2得到的是数据1 的地址
o1 = 2;//修改的是栈中o1存储的引用
Console.WriteLine(o2);//?
}
static void Main()
{
int a = 1;
int[] arr = new int[] { 1 };
Fun1(a,arr);//实参将 数据1/数组引用 赋值给形参
Console.WriteLine(a);
Console.WriteLine(arr[0]);
}
private static void Fun1(int a,int[] arr)
{
a = 2;
//arr[0] = 2;
arr = new int[] { 2 };
}
static void Main()
{
int a = 1;
//int b = a;
//装箱操作:"比较"消耗性能("最")
object o = a;
//拆箱操作:"比较"消耗性能
int b = (int)o;
int num = 100;
string str01 = num.ToString();//没装
string str02 = "" + num;//装箱
//string str02 = string.Concat("",num) //int ==>object
}
//形参object类型,实参传递值类型,则装箱
//可以通过 重载、泛型避免。
static void Main()
{
string s1 = "八戒";
string s2 = "八戒";//同一个字符串
string s3 = new string(new char[] { '八', '戒' });//将字符数组转换为字符串
string s4 = new string(new char[] { '八', '戒' });
bool r1 = object.ReferenceEquals(s3, s4);
//字符串池
//字符串的不可变性
//重新开辟空间 存储新字符串,再替换栈中引用
s1 = "悟空";
//将文本“八戒”改为“悟空”
Console.WriteLine(s1);
//每次修改,都是重新开辟新的空间存储数据,替换栈中引用
object o1 = 1;
o1 = 2.0;
o1 = "ok";
o1 = true;
//创建一个计时器,用来记录程序运行的时间
Stopwatch sw = new StopWatch();
string strNumber = "";
for (int i = 0; i < 10; i++)
{
// "" + "0"
// "0"+ "1" 每次拼接产生新的对象 替换引用 (原有的数据产生1次垃圾)
strNumber = strNumber + i.ToString();
}
sw.Stop();//计时结束
Console.WriteLine(sw.Elapsed);
//可变字符串 一次开辟可以容纳10个字符大小的空间
//优点:可以在原有空间修改字符串,避免产生垃圾
//适用性:频繁对字符串操作(增加 替换 移除)
StringBuilder builder = new StringBuilder(10);
for (int i = 0; i < 10; i++)
{
builder.Append(i);
}
builder.Append("是哒");
string result = builder.ToString();
builder.Insert(0,"builder");
//builder.Replace();
//builder.Remove();
s1 = s1.Insert(0, "s1");
}
static void Main()
{
string s1 = " sda Hisc as ";
char[] s2 = s1.ToCharArray(0, 5);
foreach (var item in s2)
{
Console.WriteLine(item);
}
string s3 = s1.Insert(0, "abs");
bool r1 = s1.Contains('d');
string s4 = s1.ToLower();
string s5 = s1.ToUpper();
int index = s1.IndexOf('i');
string s6 = s1.Substring(5);
string s7 = s1.Trim();
string[] s8 = s1.Split(new char[] { 'a' });
string s9 = s1.Replace('a', 'b');
string s10 = string.Join(' ', new string[] { "dsa", "ewq", "sxc" });
}
namespace Day07
{
[Flags] //修饰符
enum PersonStyle
{
//普通枚举
//tall=0, //0000000000
//rich=1, //0000000001
//handsome =2, //0000000010
//white =3, //0000000011
//beauty = 4 //0000000100
//标志枚举
tall = 1, //0000000001
rich = 2, //0000000010
handsome = 4, //0000000100
white = 8, //0000001000
beauty = 16 //0000010000
}
/*
选择多个枚举值
运算符 |(按位或):两个对应的二进制位中有一个为1,结果位为1
tall | rich ==> 0000000000 | 0000000001 ==> 0000000001
条件:
1.任意多个枚举值做 | 运算 的 结果不能与其他枚举值相同(值以2的N次方递增)
2.定义枚举时,使用[Flags]特性修饰
判断标志枚举 是否包含指定枚举值
运算符 &(按位与):两个对应的二进制位中都为1,结果位为1
0000000011 & 0000000001 ==> 0000000001
*/
}
static void Main(string[] args)
{
//PrintPresonStyle(PersonStyle.tall);
//00000000001 | 0000010000 ==> 0000010001
//PrintPresonStyle(PersonStyle.tall | PersonStyle.beauty);
//数据类型转换
//int ==> Enum
PersonStyle style01 = (PersonStyle)2;
//PrintPresonStyle((PersonStyle)2);
//Enum ==> int
int enumNumber =(int) (PersonStyle.beauty | PersonStyle.handsome);
//string ==> Enum
//"beauty"
PersonStyle style02 =(PersonStyle) Enum.Parse(typeof(PersonStyle), "beauty");
// Enum ==> string
string strEnum = PersonStyle.handsome.ToString();
}
private static void PrintPresonStyle(PersonStyle style)
{
if((style & PersonStyle.tall)==PersonStyle.tall)
Console.WriteLine("大个子");
else if ((style & PersonStyle.rich)== PersonStyle.rich)
Console.WriteLine("土豪");
else if ((style & PersonStyle.handsome) != 0)
Console.WriteLine("靓仔");
else if ((style & PersonStyle.white)== PersonStyle.white)
Console.WriteLine("白净");
else if ((style & PersonStyle.beauty) != 0)
Console.WriteLine("美女");
}
private static int a = 1;
private const int b = 1;
private int rIndex = 0;//报错:结构中不能有实例字段初始化设定项
struct Direction
{
private int rIndex;
public int RIndex
{
get
{
return this.rIndex;
}
set
{
this.rIndex = value;
}
}
public int CIndex { get; set; }
//因为结构体自带无参数构造函数,所以不能包含无参数构造函数
public Direction()//报错:结构不能包含显式的无参数构造函数
{
}
public Direction (int rIndex,int cIndex):this()//没有:this()好像也没报错,可能是高版本的原因
{//构造函数中,必须先为所有字段赋值
//:this() 有参数构造函数 先调用无参数构造函数,为自动属性的字段赋值
this.rIndex = rIndex;
this.CIndex = cIndex;
}
}