一、交错数组
1.概念
元素是行,四个元素,每个元素都是新的一维数组
2.定义
//交错数组棋盘不规则
//交错数组定义
int[][] array02;
//创建具有4个元素的交错数组
array02 = new int[4][];
//创建一维数组,赋值给交错数组的第一个元素
array02[0] = new int[3];
array02[1] = new int[5];
array02[2] = new int[4];
array02[3] = new int[1];
//将数据1赋值给交错数组的第一个元素的第一个元素
array02[0][0] = 1;
foreach (int[] array in array02)
{
foreach (int element in array)
{
Console.WriteLine(element);
}
}
//array02.Length 理解为获取交错数组元素数
for(int i = 0; i < array02.Length; i++)
{
for (int j = 0; j < array02[i].Length; j++)
{
Console.Write(array02[i][j]+"\t");
}
Console.WriteLine();
}
二、参数数组
//params 参数数组
//对于方法内部而言:就是普通数组
//对于方法外部(调用者而言):
//可以传递数组
//传递一组数据类型相同的变量集合
//甚至可以不传参数
//作用:简化调用者调用方法的代码
private static int Add(params int[] arr)
{
int sum = 0;
foreach (var item in arr)
{
sum += item;
}
return sum;
}
static void Main()
{
int result01 = Add(new int[] { 1, 34, 43, 54, 78 });
int result02 = Add(1, 34, 43, 54, 78);
}
注:当类型确定,个数不确定的情形 用数组
三、数据类型
类型分类
①值类型
存储数据本身
②引用类型
存储数据的引用(内存地址)
四、局部变量
1.代码图示理解
//值类型 引用类型
//int bool char string Array
//1.因为方法执行在栈中,所以在方法中声明的变量在栈中
//2.因为值类型直接存储数据,所以数据存储在栈中
//3.又因为引用类型存储数据的引用,所以数据在堆中,栈中存储数据的引用
//a在栈中 1在栈中
int a = 1;
//arr在栈中存储数组对像的引用(内存地址) 1在堆中
int[] arr = new int[] { 1} ;
2.练习:
//a在栈中 1在栈中
int a = 1;
int b = a;
a = 2;
Console.WriteLine(b);//? 1
//arr在栈中存储数组对像的引用(内存地址) 1在堆中
int[] arr = new int[] { 1} ;
int[] arr2 = arr;
arr[0] = 2;
Console.WriteLine(arr2[0]);//? 2
修改arr
//arr在栈中存储数组对像的引用(内存地址) 1在堆中
int[] arr = new int[] { 1} ;
int[] arr2 = arr;
//arr[0] = 2;//修改的是堆中的数据
arr = new int[] { 2 };//修改的是栈中的地址
Console.WriteLine(arr2[0]);//? 1
字符串
string s1 = "难";
string s2 = s1;
s1 = "女";//修改的是栈中存储的引用
Console.WriteLine(s2);
看修改的是栈中的还是堆中的就看左边的类型是什么(有无中括号)
3.方法中的堆栈练习
static void Main()
{
int a = 1;
int[] arr = new int[] { 1 };
Fun1(a,arr);//a实参将 数据1 赋值给形参 arr实参将 堆中数据1的地址 赋值给形参
Console.WriteLine(a);//?1
Console.WriteLine(arr[0]);//?2
}
private static void Fun1(int a, int[]arr)
{
a = 2;
arr[0] = 2;
//arr = new int[] { 2 }; 将arr地址改变指向2
}
尽管字符串(string
)是引用类型,当你将一个字符串作为参数传递给一个方法时(如你的 WordReversal
方法),你传递的是对字符串对象的引用的副本,而不是原始引用本身。
private static string WordReversal(string str)传递的是值
4.引用参数ref 与输出参数 out
static void Main4()
{
int a = 1;
int[] arr = new int[] { 1 };
Fun1(a,arr);//a实参将 数据1 赋值给形参 arr实参将 堆中数据1的地址 赋值给形参
Console.WriteLine(a);//?1
Console.WriteLine(arr[0]);//?2
Fun2(ref a);
Console.WriteLine(a);//?2
// 区别2:输出参数前可以不赋值
int a3;//用于接受方法的结果
Fun3(out a3);
}
//值参数:按值传递--传递实参变量存储的内容
//作用:改变数据
private static void Fun1(int a, int[]arr)
{
a = 2;
arr[0] = 2;
//arr = new int[] { 2 }; 将Fun1中arr地址改变指向2
}
//引用参数:按引用传递--传递实参变量自身的内存地址
//作用:改变数据
private static void Fun2(ref int a)
{//方法内部修改引用参数 实质上修改了实参变量
a = 2;
}
//输出参数:按引用传递--传递实参变量自身的内存地址
//作用:返回结果
private static void Fun3(out int a)
{//区别1:方法内部必须为输出参数赋值
//区别2:输出参数前可以不赋值
a = 2;
}
5.练习
练习1:定义两个整数交换的方法
练习2:根据矩形长、宽计算面积(长*宽)与周长
//练习1:定义两个整数交换的方法
private static void Swop(ref int a ,ref int b)
{
int tempt = a;
a = b;
b = tempt;
}
//练习2:根据矩形长、宽计算面积(长*宽)与周长
private static void AreaPerimeterByJ(int chang, int kuan, out int area, out int perimeter)
{
area = chang * kuan;
perimeter = 2 * (chang * kuan);
}
static void Main()
{
int a = 1; int b = 2;
swop(ref a, ref b);
Console.WriteLine(a + "\t" + b);
int area; int perimeter;
AreaPerimeterByJ(a, b, out area, out perimeter);
Console.WriteLine(area + "\t" + perimeter);
}
五、拆装箱
考点
//形参object类型,实参传递值类型,则装箱
//可以通过 重载、泛型 避免
//装箱操作:"比较"消耗性能(“最”)--值类型到object类型的转换
//拆箱操作:"比较"消耗性能--object类型到值类型的转换
int a = 1;
//装箱操作:"比较"消耗性能(“最”)--值类型到object类型的转换
object o = a;
//拆箱操作:"比较"消耗性能--object类型到值类型的转换
int b = (int)o;
//没有装箱操作
int num = 100;
string str = num.ToString();
//有装箱操作
string str02 = "" + num;//字符串与值类型直接相加
六、字符串
1.字符串池
string s1 = "八戒";
string s2 = "八戒";
//字符串池,会判断堆内是否有相同的字符串,有就是那个值的引用
string s3 = new string(new char[]('八','戒'));
string s4 = new string(new char[]('八', '戒'));
bool r1 = object.ReferenceEquals(s1, s2);//为真,s1与s2存着同一个引用
bool r2 = object.ReferenceEquals(s3, s4);//为假,s3与s4存着不是同一个引用
2、字符串的不可变性
重新开辟空间 存储新字符串,再替换栈中引用
因为可变会改变其他地址中的值
s1 = "悟空";//重新开辟空间 存储新字符串,再替换栈中引用
string strNumber = "";
for (int i = 0; i < 10; i++)
{
//每次拼接都会产生新的对象替换引用,之前的对象就成了垃圾
strNumber += i.ToString();
}
3.可变字符串
//可变字符串 一次开辟可以容纳10个字符大小的空间
//优点:可以在原有空间修改字符串
//适用性:频繁对字符串操作(增加 替换 插入)
//建议:给适当大小空间
StringBuilder builder = new StringBuilder(10);
for (int i = 0;i < 10; i++)
{
builder.Append(i);
}
string result = builder.ToString();
//builder.Insert(); 无返回值
s1 = s1.Insert(0, s1);
4.练习(字符串的操作)
①单词反转
How are you ==>you are How
private static void WordReversal(ref string str)
{
string[] strArray = str.Split(' ');
Array.Reverse(strArray);
StringBuilder builder = new StringBuilder(str.Length);
builder.AppendJoin(' ',strArray);
str = builder.ToString();
}
static void Main()
{
string str = "How are you";
WordReversal(ref str);
Console.WriteLine(str);
}
②字符反转
How are you ==>uoy era woH
private static void LetterReversal(ref string str)
{
char[] chars = str.ToCharArray();
Array.Reverse(chars);
StringBuilder builder = new StringBuilder(str.Length);
for (int i = 0; i < str.Length; i++)
{
builder.Append(chars[i]);
}
str = builder.ToString();
}
static void Main()
{
string str = "How are you";
LetterReversal(ref str);
Console.WriteLine(str);
}
③查找指定字符串中不重复出现的文字(重复的文字保留1个)
private static void FindDupicateLetter(ref string str)
{
for (int i = 0; i < str.Length; i++)
{
for (int j = i+1; j < str.Length-1;j++)
{
if (str[i] == str[j])
{
str = str.Remove(j, 1);
j--;
}
}
}
}
static void Main()
{
string str = "How are you";
FindDupicateLetter(ref str);
Console.WriteLine(str);
}