文章目录
- C#数组
- 类型分析
- 多维数组
- 交错数组
- 数组的属性和方法
- 上期习题答案
- 本期习题
C#数组
数组是一个用来存储相同类型数据的、固定大小的、具有连续内存位置的顺序集合。数组中的每个元素都对应一个索引值,索引从 0 开始依次递增,我们可以通过索引来访问数组中的指定元素
假如我们要存储 100 名学生的分数,若使用普通变量的话可能需要定义 100 整型变量,例如 number0、number1、…、number99。而如果使用数组就简单的多了,只需要定义一个长度为 100 的整型数组,例如 numbers,然后使用 numbers[0]、numbers[1]、…、numbers[99]([ ]
中的数字就是数组的索引)就可以访问数组中的每个元素。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _02_数组
{
internal class Program
{
static void Main(string[] args)
{
//一维数组是最简单并且最常用的一种数组
//1.数组的声明,声明数组类似声明变量,需要指定数组中存储的数据类型
一般数组变量的名称以复数形式命名 (加s);
//格式: 数据类型[] 变量名;
int[] ints; //声明一个用于存储int类型的数组
char[] chars;//声明一个用于存储char类型的数组
//2.数组的初始化,注意两边的类型必须一致
//格式: 变量名 = new 类型[数组的长度]
ints = new int[10];
chars = new char[23];
//简写为:
double[] doubles = new double[7];
//错误写法
// double[7] doubles = new double[7];
//注意:数组必须进行初始化后才能进行后续操作
//数组初始化后,C#会自动在数组中填充对应类型的默认值进行占位
//数字类型默认值 0
// bool类型默认值为false
// char类型默认值\0
//string类型默认null
int[] ints1 = new int[10];
bool[] bolls = new bool[10];
char[] chars1 = new char[10];
//我们也可以在初始化数组的时候指定他的初始值
string[] names = new string[3] { "吴亦凡", "罗志祥", "李云迪" };
//如果初始化时制定了数组的初始值,那么就可以省略指定数组的长度
会自动根据数组的初始值指定数组的长度
string[] names1 = new string[] { "吴亦凡", "李云迪" };
//数组的声明如果进行了初始化 可以省略 new 数据类型[]
string[] names2 = { "吴亦凡", "罗志祥" };
//数组的操作
//数组中数据操作都是基于索引的,索引从0开始,到数组的 长度-1 结束
用于访问数组中存储的数据
//数组中数据的读取: 数组[索引]
//数组中数组的设置: 数组[索引]=值
names[1] = "李易峰";
Console.WriteLine("names[0]:" + names[0]);
Console.WriteLine("names[1]:" + names[1]);
// 练习:定义第一个长度为50的数组,其中存储50个偶数
int[] nums = new int[50];
//nums[0] = 2;
//nums[1] = 4;
//nums[2] = 6;
//Length 是一个32位的整数 表示数组的长度
for (int i = 0; i < nums.Length; i++)
{
nums[i] = i * 2;
}
//数组的遍历
//1.可以使用for循环来遍历数组
for (int i = 0; i < nums.Length; i++)
{
Console.WriteLine($"数组的第{i}位是:{nums[i]}");
}
Console.WriteLine("----------------------");
//2.还可以使用foreach进行遍历
//格式: foreach(数组数据类型 变量名 in 数组){}
foreach (int v in nums)
{
//v就表示数组中的每一项数据
Console.WriteLine(v);
}
//foreach优缺点:
// 优点: 简洁
// 缺点:
// 1.无法访问到当前数据所在的索引
// 2.无法修改数组
// 3.无法终止(for可以用break continue进行循环控制)
//比如下面这个需求foreach无法实现:
将nums数组中的每一项增加50
for (int i = 0; i < nums.Length; i++)
{
// nums[i] = nums[i] + 50;
nums[i] += 50;
}
}
}
}
类型分析
int [] ints6 = new int[] { 1, 2, 3, };
int [] ints7 = ints6;
ints6[0] = 666;
Console.WriteLine(ints7[0]);//666
数组是引用数据类型
多维数组
多维数组(也可称为矩形数组),它可以是二维的,也可以是三维的,多维数组中的数据以类似表格(行、列)的形式存储,因此也被称为矩阵。
多维数组中最简单的形式是二维数组,我们可以将二维数组看作是一个表格,这个表格中具有相应的行数和列数,下图中展示了一个包含 3 行 4 列的二维数组。
使用arr[i, j]
的形式来访问二维数组中的每个元素,其中 arr 为数组的名称,而 i 和 j 则是数组元素的索引,类似于表格中的行和列
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _03_多维数组
{
internal class Program
{
static void Main(string[] args)
{
//C#支持多维数组(矩形数组),最简单的多维数组,就是二维数组
//一个二维数组的定义被认为是一个带有行和列的表格
//多维数组的声明:
//1.二维数组:
//数据类型[,]变量名 = new 数据类型[2,3]
//2.三维数组:
//数据类型[,,]变量名=new 数据类型[2,3,5]
//3.四维数组:
//数据类型[,,,] 变量名 =new 数据类型[2,3,4,5]
//....
//N维数组
//数据类型[N-1个逗号] 变量名 =new 数据类型[每个维度的长度];
//一维数组的初始化
int[] ints1 = new int[3] { 666, 777, 888 };
//多维数组的初始化
//二维数组
int[,] ints2 = new int[3, 4] {
{1,2,3, 4 },
{1,2,3, 4 },
{1,2,3, 4 }
};
//三维数组
int[,,] ints3 = new int[3, 4, 2]
{
{
{1,2 },
{1,2 },
{1,2 },
{1,2 },
},
{
{1,2 },
{1,2 },
{1,2 },
{1,2 },
},
{
{1,2 },
{1,2 },
{1,2 },
{1,2 },
}
};
//可以根据初始值进行自动推导
string[,] strings1 = new string[,]
{
{ "a","b","c"},
{ "aa","bb","cc"},
{ "aaa","bbb","ccc"},
};
Console.WriteLine(strings1[0,0]);
Console.WriteLine(strings1[0, 1]);
Console.WriteLine(strings1[1, 0]);
Console.WriteLine(strings1[2, 0]);
strings1[2, 0] = "88888";
Console.WriteLine(strings1[2, 0]);
string[,] strings2 = new string[5, 10];
strings2[0, 0] = "行:0,列:0";
strings2[0, 1] = "行:0,列:1";
strings2[0, 2] = "行:0,列:2";
for (int i = 0; i < 5; i++)
{
for(int j = 0; j < 10; j++)
{
strings2[i, j] = $"行:{i},列:{j}";
}
}
strings2[3, 7] = "吴亦凡";
Console.WriteLine(strings2[3,7]);
//遍历
Console.WriteLine("---------------------");
//多维数组的遍历 foreach可以循环获取每一项的值, 无论数组是几维的
foreach (string v in strings2)
{
Console.WriteLine(v);
}
//Length 属性获取到的是各个维度存储的数据的总长度(数据的总个数)
Console.WriteLine(strings2.Length);
//获取对应维度中的元素的个数(长度)
Console.WriteLine(strings2.GetLength(0));
Console.WriteLine(strings2.GetLength(1));
for (int i = 0; i < strings2.GetLength(0); i++)
{
for (int j = 0; j < strings2.GetLength(1); j++)
{
Console.WriteLine(strings2[i, j]);
}
}
//定义一个二维数组叫做arr3 arr3[0,3]=>10 arr3[1,2]=>20 arr3[2,2]=>30
int[,] arr3 = new int[3, 4]
{
{0,0,0,10}, //0行
{0,0,20,0 }, //1行
{0,0,30,0 } //2行
//0列 1列 2列 3列 4列
};
Console.WriteLine(arr3[0,3]);//10
Console.WriteLine(arr3[1,2]);//20
Console.WriteLine(arr3[2,2]);//30
}
}
}
交错数组
交错数组其实就是元素为数组的数组,换句话说就是交错数组中的每个元素都可以是维度和大小不同的数组,所以有时交错数组也被称为“数组的数组”。
交错数组和多维数组的区别在于,交错数组的每一行的长度可以不同
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _04_交错数组
{
internal class Program
{
static void Main(string[] args)
{
//交错数组:就是装着数组的数组,交错数组存储的也是数组
//交错和多维数组的区别:交错数组的每一个的长度都可以不同
int[,] ints = new int[,]
{
{1,2},
{3,4 }
};
//交错数组的定义:
int[] ints1;//一层交错数组,就是普通的一维数组
int[][] ints2;//二层交错数组,数组中装着一层交错数组
int[][][] ints3;//三层交错数组,数组中装着二层交错数组
int[] ints4 = new int[] {1,2,3};
int[][] ints5 = new int[][] {
new int[] {1,3},
new int[] {1,2,3}
};
int[][][] ints6 = new int[][][] {
new int[][] {
new int[] {1,3},
new int[] {1,2,3}
},
new int[][] {
new int[] {1,3},
new int[] {1,2,3}
}
};
int[] ints7_1 = new int[] { 1, 3, 4, 4 };
int[] ints7_2 = new int[] { 1, 5 };
int[] ints7_3 = new int[] { 1, 6 };
int[] ints7_4 = new int[] { 1, 3,4 };
//注意:如果初始化的时候,没有指定初始值必须指定第一层的长度
int[][] ints7 = new int[][] {
ints7_1,
ints7_2,
ints7_3,
ints7_4,
};
//int[] arr = ints7[0];
//Console.WriteLine(arr[3]);
//交错数组 通过 数组名[第一层数组索引][第二层数组索引]
Console.WriteLine(ints7[0][3]);
ints7[0][3] = 888;
Console.WriteLine(ints7[0][3]);
//数据的个数
Console.WriteLine(ints7.Length);
Console.WriteLine(ints7[1].Length);
//遍历
//交错数组其实就是数组里面存数组,可以使用foreach 一层一层循环
foreach (int[] v in ints7)
{
foreach(int vv in v)
{
Console.WriteLine(vv);
}
}
for (int i = 0; i < ints7.Length; i++)
{
// Console.WriteLine(ints7[i]);//数组
for (int j = 0; j < ints7[i].Length; j++)
{
Console.WriteLine(ints7[i][j]);
}
}
}
}
}
数组的属性和方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _05_数组的属性和方法
{
internal class Program
{
static void Main(string[] args)
{
//所有的数组都是Array类的实例 Array类提供了一系列属性和方法
int[] ints = { 1, 2, 3, 4, 4 };
int[,,] ints1 =
{
{
{ 1, 2, },
{ 3, 4, },
},
{
{ 1, 2, },
{ 3, 4, },
}, {
{ 1, 2, },
{ 3, 4, },
}
};
Console.WriteLine(ints.Length);// 返回一个32位的整数,表示数组的长度
Console.WriteLine(ints.LongLength);//返回一个64位的整数,表示数组的长度
Console.WriteLine(ints.Rank);//返回数组的维度
Console.WriteLine(ints1.Rank);
Console.WriteLine("-----------------------");
//方法
int[] ints2 = { 1, 2, 3, 4, 5, 6, 7 };
//将数组中指定的数据恢复为对应类型的默认值
//参数1:需要恢复的数组
//参数2:开始的索引
//参数3:恢复的个数
Array.Clear(ints2, 1, 4);
WriteArr(ints2);//[1,0,0,0,5,6,7,]
int[] ints3 = new int[10];
//将参数1 数组的数据复制到参数2数组中,由参数3决定复制的个数
//注意: 1.复制的个数不能超过源数组的长度
// 2.复制的个数不能超过新数组的长度
Array.Copy(ints2, ints3, 6);//[1,0,0,0,0,6,0,0,0,0,]
WriteArr(ints3);
//复制的是数组中的数据,这是两个不同的数组,不会互相影响
ints2[0] = 100;
Console.WriteLine(ints3[0]);
//------------------------------
//复制的是数组中的数据
//当数组中存储的是值类型时,数组存储的是值本身
//当数组中存储的是引用类型时,数组存储的是引用类型的内存地址
People[] peoples1 =
{
new People() { Name = "吴亦凡" }
};
People[] peoples2 = new People[2];
Array.Copy(peoples1, peoples2, peoples1.Length);
peoples2[0].Name = "罗志祥";
Console.WriteLine(peoples1[0].Name);//罗志祥
peoples2[0] = new People() { Name = "权志龙" };
Console.WriteLine(peoples1[0].Name);//罗志祥
//--------------------------------
int[] ints4 = { 2, 4, 5, 6, 7, 8, 9 };
int[] ints5 = new int[6];
/*
* 参数1:被复制的数组
* 参数2:复制的开始的位置
* 参数3:复制到的目标数组
* 参数4:目标数组的开始位置
* 参数5:复制的个数
*/
Array.Copy(ints4, 2, ints5, 1, 4);//[0,5,6,7,8,0,]
WriteArr(ints5);
//反转数组
Array.Reverse(ints5);
WriteArr(ints5);
//查找对应数据在数组中首次出现的位置,有则返回当前数据的索引位置,没有则返回-1
Console.WriteLine(Array.IndexOf(ints5,55));
//参数3是指定开始查询的位置
Console.WriteLine(Array.IndexOf(ints5, 0,3));
//参数4:指定查询的个数 从ints5中查询0 从2开始 查询3个
Console.WriteLine(Array.IndexOf(ints5, 0, 2,3));
}
public static string WriteArr(int[] arr) //WrriterArr为自定义的打印方法
{ //方便直接查看数组
string s = "[";
for (int i = 0; i < arr.Length; i++)
{
s += arr[i] + ",";
}
s += "]";
Console.WriteLine(s);
return s;
}
}
class People
{
public string Name;
}
}
上期习题答案
- 将字符串大写转小写,小写转大写
例:ASDFGHasdfg===>asdfghASDFG
public static string Test(string s)
{
string res = "";
//判断是大写
for (int i = 0; i < s.Length; i++)
{
//s[i] char
//转成string
//string str1= s[i] + "";
//char[] cs =new char[] { s[i]};
//string str2 = new string(cs);
string str3 = s[i].ToString();
if (str3 == str3.ToUpper())
{
//大写
res += str3.ToLower();
}
else
{
//小写
res += str3.ToUpper();
}
}
return res;
}
- 用户输入一句话,判断话中有没有吴亦凡,如果有吴亦凡就替换成这种形式然后输出,如:加拿大劣迹男艺人吴亦凡===>加拿大劣迹男艺人***
static public string Test2(string x)
{
string s = "";
if (x.Contains("吴亦凡"))
{
s = x.Replace("吴亦凡", "***");
}
return s;
}
- 让用户输入一句话含有e的话,找出所有e的位置
static public void Test3(string x)
{
for (int i = 0; i < x.Length; i++)
{
if (x[i]=='e')
{
Console.WriteLine(i);
}
}
}
- 自定义方法
Concat() 连接字符串 Contains(“吴亦凡”,“凡)”)
StartsWith() IndexOf() LastIndexOf() Remove()
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
namespace _01_昨天作业
{
internal class Program
{
static void Main(string[] args)
{
//Console.WriteLine("吴亦凡是一个劣迹明星".IndexOf("亦凡"));
Console.WriteLine(Test("HIDhiHIHDBDNdfhsihfdn"));//hidHIhihdbdnDFHSIHFDN
Console.WriteLine(Concat("afdsf", "1234", "3fgdas", "fdasf"));
Console.WriteLine(Contains("吴亦凡", "凡"));
Console.WriteLine(Contains("吴亦凡是一个劣迹明星", "吴凡"));
Console.WriteLine(IndexOf("吴亦凡", "凡"));
Console.WriteLine(IndexOf("吴亦凡是一个劣迹明星", "亦凡"));
}
static public string Concat(params string[] strings)
{
string str = "";
for (int i = 0; i < strings.Length; i++)
{
//Console.WriteLine(strings[i]);
str += strings[i];
}
return str;
}
//
public static bool Contains(string beseString,string value)
{
//for (int i = 0; i < beseString.Length; i++)
//{
// if (beseString[i].ToString()==value)
// {
// //return 除了返回一个结果
// //还可以终止函数
// return true;
// }
//}
//return false;
//IndexOf("abc","aaa"); 1!=-1; ==>true
return IndexOf( beseString, value) != -1;
}
//("吴亦凡是一个劣迹明星", "吴亦凡")
public static int IndexOf(string beseString, string value)
{
//考虑多个字符串的时候,应该从源字符串中取出对应长度的字符串进行对比
int len = value.Length;//3
//循环:因为查询的字符串的长度不一定为1,那么循环也没有必要总是查询到最后
for (int i = 0; i <=beseString.Length-len; i++)
{
string s = "";//存储拼接的字符串
//内部循环用于拼接对比的字符串 从i开始
for (int j = i; j <=i+len-1; j++)
{
s += beseString[j];
}
//对比字符串是否相同
if (s==value)
{
return i;
}
}
return -1;
}
// <summary>对 类 属性 字段 方法... 功能的描述
// <param> 对参数的描述
// <returns> 对返回值的描述
/// <summary>
/// 从后向前查询参数在源字符串首次出现的索引的位置
/// </summary>
/// <param name="beseString">被查询的源字符串</param>
/// <param name="value">查询的字符串</param>
/// <returns>如果存在 返回索引 不存在,返回-1</returns>
static public int LastIndexOf(string beseString, string value)
{
int len = value.Length;
for (int i = beseString.Length - len; i >= 0; i--)
{
string s = "";
for (int j = i; j <= i + len - 1; j++)
{
s += beseString[j];
}
if (s == value)
{
return i;
}
}
return -1;
}
static public bool StartsWith(string beseString, string value)
{
//如果value的长度大于beseString的长度 直接返回false
if (value.Length > beseString.Length) return false;
//1.循环value
//2.将value对应索引位置的字符和源字符串对应位置的字符比较
// 2-1相同则继续循环
// 2-2不同则直接返回false
// 3.循环结束返回true
for (int i = 0; i < value.Length; i++)
{
if (value[i] != beseString[i])
{
return false;
}
}
return true;
}
static public string Remove(string beseString, int startIndex,int count)
{
string res = "";
//1.循环beseString
//2.判断当前的索引是否小于startIndex
//2.1如果小于开始的索引,或者删除的个数为0 直接拼接
//2.2 如果不小于 跳过拼接 并且删除的个数 -1
//3.循环结束 返回新的字符串
for (int i = 0; i < beseString.Length; i++)
{
if (i<startIndex||count==0)
{
res += beseString[i];
}
else
{
count--;
}
}
return res;
}
}
}
本期习题
-
定义一个数组,再逆序存储它的值 (自定义Reverse)
如int[] a = new int[] { 1,9,3,4 };
经过一系列操作后将数组变成: {4,3,9,1} -
定义一个长度为 50 的数组,数组里面的值是从 0~99 随机产生的 .
求出其中 30 出现的次数, -
实现一个方法用于打乱一个数组
-
将数组中的数据排序 (冒泡排序,选择排序)