交错数组
每个元素都为一维数组
using System;
namespace day6
{
class Program
{
static void Main(string[] args)
{
// 交错数组 参数数组 数据类型
int[][] array01;
// 创建具有4个元素的交错数组
array01 = new int[4][];
// 创建一维数组 赋值给 交错数组的第一个元素
array01[0] = new int[3];
array01[1] = new int[5];
array01[2] = new int[4];
array01[3] = new int[1];
// 交错数组赋值
array01[0][0] = 1;
array01[1][2] = 2;
array01[1][4] = 3;
array01[2][1] = 4;
array01[2][3] = 5;
// 控制台显示
foreach (var array in array01)
{
foreach (var element in array)
Console.Write(element + "\t");
Console.WriteLine();
}
for (int r = 0; r < array01.Length; r++)
{
for (int c = 0; c < array01[r].Length; c++)
Console.Write(array01[r][c] + "\t");
Console.WriteLine();
}
}
}
}
params
static void Main()
{
int result01 = Add(new int[] {1, 24, 35, 12, 6});
int result02 = Add(1, 24, 35, 12, 6);
Console.WriteLine(result01);
Console.WriteLine(result02);
}
// 一个整数相加的方法
// 当类型确定 个数不确定时
// params 参数数组
// 对于方法内部而言:就是个普通数组
// 对于方法外部(调用者)而言:
// 可以传递数组
// 传递一组数据类型相同的变量集合
// 可以不传递参数
// 作用:简化调用者调用方法的代码
private static int Add(params int[] arr)
{
int count = 0;
foreach (var item in arr)
count += item;
return count;
}
C#中数据类型分类
通用类型系统CTS(Common Type System)是.NET框架中的一个组成部分,为所有面向.NET框架的语言定义了数据类型的规则。
值类型:存储 数据 本身
引用类型:存数据的 引用(内存地址)
局部变量
定义在方法内部的变量
变量名就是内存地址的别名
局部变量中的值类型:声明在栈中,数据存储在栈中
局部变量中的引用类型:声明在栈中,数据存储在堆中,栈中只存引用(内存地址)
方法执行在栈中,所以方法中声明的变量都在栈中
值类型存储数据 --> 局部变量中数据存储在栈上
引用类型存引用 --> 局部变量中数据存储在堆中
2048核心算法-改01-上下左右移动
// 2048核心算法-改01-上下左右移动
static void Main()
{
int[,] map = new int[4, 4]
{
{2,2,4,8},
{2,4,4,4},
{0,8,4,0},
{2,4,0,4}
};
PrintArray(map);
Console.WriteLine("上移");
MoveUp(map);
PrintArray(map);
Console.WriteLine("下移");
MoveDown(map);
PrintArray(map);
Console.WriteLine("左移");
MoveLeft(map);
PrintArray(map);
Console.WriteLine("右移");
MoveRight(map);
PrintArray(map);
}
/// <summary>
/// 控制台展示矩阵
/// </summary>
/// <param name="array">矩阵</param>
private static void PrintArray(Array array)
{
for (int r = 0; r < array.GetLength(0); r++)
{
for (int c = 0; c < array.GetLength(1); c++)
{
Console.Write(array.GetValue(r,c) + "\t");
}
Console.WriteLine();
}
}
/// <summary>
/// 数组非零元素移至左侧
/// </summary>
/// <param name="array">一维数组</param>
/// <returns>一维数组</returns>
private static void RemoveZero(int[] array)
{
// 新数组
int[] newArray = new int[array.Length];
// 将非零元素依次赋值给新数组
int index = 0;
for (int i = 0; i < array.Length; i++)
if (array[i] != 0)
newArray[index++] = array[i];
newArray.CopyTo(array,0);
// for (int i = 0; i < array.Length; i++)
// array[i] = newArray[i];
}
/// <summary>
/// 合并相同数据
/// </summary>
/// <param name="array">一维数组</param>
/// <returns>一维数组</returns>
private static void Merge(int[] array)
{
RemoveZero(array);
// 合并数据
for (int i = 0; i < array.Length-1; i++)
{
// 相邻相同
if (array[i] != 0 && array[i] == array[i+1])
{
array[i] += array[i + 1];
array[i + 1] = 0;
// 统计合并位置
}
}
RemoveZero(array);
}
/// <summary>
/// 2048上移
/// </summary>
/// <param name="map">矩阵</param>
private static void MoveUp(int[,] map)
{
// 从上到下 获取列数据,形成一维数组
int[] mergeArray = new int[map.GetLength(0)];
for (int c = 0; c < map.GetLength(1); c++)
{
for (int r = 0; r < map.GetLength(0); r++)
mergeArray[r] = map[r, c];
Merge(mergeArray);
for (int r = 0; r < map.GetLength(0); r++)
map[r, c] = mergeArray[r];
}
}
/// <summary>
/// 2048下移
/// </summary>
/// <param name="map">矩阵</param>
private static void MoveDown(int[,] map)
{
// 从下到上 获取列数据,形成一维数组
int[] mergeArray = new int[map.GetLength(0)];
for (int c = 0; c < map.GetLength(1); c++)
{
for (int r = map.GetLength(0)-1; r >= 0 ; r--)
// 从头到尾存入一维数组
mergeArray[map.GetLength(0)-1-r] = map[r, c];
Merge(mergeArray);
for (int r = map.GetLength(0)-1; r >= 0 ; r--)
map[r, c] = mergeArray[map.GetLength(0)-1-r];
}
}
/// <summary>
/// 2048左移
/// </summary>
/// <param name="map">矩阵</param>
private static void MoveLeft(int[,] map)
{
// 从左到右 获取列数据,形成一维数组
int[] mergeArray = new int[map.GetLength(1)];
for (int r = 0; r < map.GetLength(0); r++)
{
for (int c = 0; c < map.GetLength(1); c++)
mergeArray[c] = map[r, c];
Merge(mergeArray);
for (int c = 0; c < map.GetLength(1); c++)
map[r, c] = mergeArray[c];
}
}
/// <summary>
/// 2048右移
/// </summary>
/// <param name="map">矩阵</param>
private static void MoveRight(int[,] map)
{
// 从右到左 获取列数据,形成一维数组
int[] mergeArray = new int[map.GetLength(1)];
for (int r = 0; r < map.GetLength(0); r++)
{
for (int c = map.GetLength(1) - 1; c >= 0; c--)
mergeArray[map.GetLength(1) - 1 - c] = map[r, c];
Merge(mergeArray);
for (int c = map.GetLength(1) - 1; c >= 0; c--)
map[r, c] = mergeArray[map.GetLength(1) - 1 - c];
}
}
引用参数与输出参数
static void Main()
{
int a2 = 1;
Fun2(ref a2);
Console.WriteLine(a2); // 2
int a3 = 1;
Fun3(out a3);
Console.WriteLine(a3); // 2
}
// 值参数:按值传递 -- 传递实参变量存储的内容
private static void Fun1(int a, int[] arr) {}
// 引用参数:按引用传递 -- 传递实参变量自身的内存地址
// 作用:改变数据
private static void Fun2(ref int a)
{// 方法内部修改引用参数 实质上就是修改实参变量
a = 2;
}
// 输出参数:按引用传递 -- 传递实参变量自身的内存地址
// 作用:返回结果 返回值有两个及以上结果时
private static void Fun3(out int a)
{// 区别1:方法内部必须为输出参数赋值
// 区别2:输出参数 传递 之前可以不赋值
// 变量用于接收方法返回的结果
a = 2;
}
static void Main()
{
int num01 = 100, num02 = 200;
Swap(ref num01,ref num02);
int area, perimeter;
CalculateRect(15,20,out area,out perimeter);
}
// 练习1:定义两个整数交换
private static void Swap(ref int one, ref int two)
{
int temp = one;
one = two;
two = temp;
}
// 练习2:长宽计算周长面积
private static void CalculateRect(int lenght, int width, out int area, out int perimete)
{
area = lenght * width;
perimete = (lenght + width) * 2;
}
int result;
bool re = int.TryParse("250", out result);
垃圾回收器
GC(Garbage Collection)是CLR中一种针对托管堆自动回收释放内存的服务。
GC线程从栈的引用开始跟踪,从而判断哪些内存是正在使用的,若GC无法跟踪到某一块堆内存,那么就认为这块内存不再使用了,即为可回收的。
装箱 box 拆箱 unbox
装箱:值类型 隐式 转换为object类型或由此值类型实现的任何接口类型的过程
1.在堆中开辟内存空间
2.将值类型数据赋值到堆中
3.返回堆中新分配对象的地址
拆箱:从object类型到值类型或从接口类型到现实该接口的值类型的 显示 转换
1.判断给定类型是否是装箱时的类型
2.返回已装箱实例中属于原值类型字段的地址
// 拆装箱
static void Main()
{
int a = 1;
// 装箱操作:“比较”消耗性能(“最”)
object o = a;
// 拆箱操作:”比较“消耗性能
int b = (int) o;
}
int num = 100;
string str01 = num + ""; // 有一次装箱操作
//string str01 = string.Concat("", num) // int ==> object
string str02 = num.ToString(); // 性能优化
形参object类型,实参传递值类型,则装箱
可以通过 重载、泛型 避免。
字符串
1.具有字符串池特性 目的:提高内存利用率
2.具有不可变性
可变字符串
// 可变字符串 一次开辟可以容纳10个字符大小的空间
// 优点:可以在原有空间修改内容,避免产生垃圾
StringBuilder bulider = new StringBuilder(10);
for (int i = 0; i < 10; i++)
{
bulider.Append(i);
}
bulider.Append("1213112312312");
string result = bulider.ToString();
// bulider.Insert();
// bulider.Replace();
// bulider.Remove();