第6讲数组

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第6讲数组
数组是具有相同类型的一组数据。

数组按照数组名、数据元素的类型和维数来进行描述。

当访问数组中的数据时,可以通过下标来指明。

数组具有以下属性。

(1)数组可以是一维、多维或交错的。

(2)数值数组元素的默认值设置为0或空。

(3)数组的索引从0开始:具有n个元素的数组的索引是0~n-1。

(4)数组元素可以是任何类型,包括数组类型。

一、一维数组
1.数组的声明
数据类型[] 数组名
如:
int[] myArray;
数组的大小不是其类型的一部分,声明一个数组时,不用管数组长度如何。

2.数组对象的创建
声明数组并不实际创建它们。

在C#中,使用new关键字创建数组的对象。

数组名=new 数据类型[数组大小表达式];
如:
myArray=new int[5];
此数组包含myArray[0]~myArray[4]
new运算符用于创建数组并将数组元素初始化它们的默认值。

此例初始化为0。

如:
String[] myStringArray=new string[6]
此数组包含myStringArray[0]~myStringArray[5],数组元素初始化为空。

3.一维数组的初始化
数据类型[] 数组名=new 数据类型[] {初值表};
例:
int[] myArray = new int[]{1,3,5,7,9};

int[] myArray;
myArray = new int[]{1,3,5,7,9};

int[] myArray= {1,3,5,7,9};
4.一维数组元素的访问
数组名[下标]
(1)用foreach遍历数组:
int[] myArray= {1,3,5,7,9};
foreach (int i in myArray)
{
Console.WriteLine(i);
}
(2)用for语句遍历数组
int[] myArray= {1,3,5,7,9};
for (int i = 0; i < 5; i++)
{
Console.WriteLine(myArray[i]);
}

int[] myArray= {1,3,5,7,9};
for (int i = 0; i < myArray .Length ; i++)
{
Console.WriteLine(myArray[i]);
}
冒泡排序:
int[] arr = new int[] { 10, 8, 3, 15, 26, 11, 30 };
for (int j = 1; j < arr.Length; j++)
{
for (int i = 0; i < arr.Length - j; i++)
{
if (arr[i] < arr[i + 1])
{
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i] + " ");
}
二、值类型和引用类型
值类型在栈(Stack)上分配,而引用类型在堆(Heap)上分配。

数组和字符串是引用类型。

int[] arr={1,3,5,7,9};
栈堆
例:
int i1 = 100; int i2 = i1; i1=50;
Console .WriteLine("i1=" + i1 + ";i2=" + i2);
i1i2

i1i2

int [] arr1 = { 1, 3, 5, 7, 9 }; int [] arr2 = arr1; arr1[0] = 500;
Console .Write("数组arr1的值为:"); foreach (int i in arr1) {
Console .Write(i + " "); }
Console .Write("数组arr2的值为:"); foreach (int i in arr2) {
Console .Write(i + " ");
}
arr1arr2


栈堆
arr2
数组复制:
int[] arr1 = { 1, 3, 5, 7, 9 };
int[] arr2 = new int[arr1.Length ];
arr1.CopyTo(arr2, 0);//复制数组
arr1[0] = 500;
Console.Write("数组arr1的值为:");
foreach (int i in arr1)
{
Console.Write(i + " ");
}
Console.Write("数组arr2的值为:");
foreach (int i in arr2)
{
Console.Write(i + " ");
}
字符串是一种特殊的引用类型,它是不可变的。

也就是说,字符串在创建之后再也不能改变,其中包括变长、变短或者修改其中的任何字符。

string s1 = "一个字符串";
string s2 = s1;
Console.WriteLine("s1是:" + s1);
Console.WriteLine("s2是:" + s2);
s1 = "另一个字符串";
Console.WriteLine("s1现在是:" + s1);
Console.WriteLine("s2现在是:" + s2);
二、多维数组
1.多维数组的声明与创建
int[,] arr=new int[3,2];
int[,,] arr=new int[4,2,3];
2.多维数组的初始化
int[,] numbers=new int[3,2]{{1,2},{3,4},{5,6}};
string[,] names=new string[2,2]{{“A1”,”A2”},{“B1”,”B2”}};
省略数组的大小:
int[,] numbers=new int[,]{{1,2},{3,4},{5,6}};
string[,] names=new string[,]{{“A1”,”A2”},{“B1”,”B2”}};
省略new运算符:
int[,] numbers= {{1,2},{3,4},{5,6}};
string[,] names={{“A1”,”A2”},{“B1”,”B2”}};
3.多维数组的操作
引用方式:
数组名[下标表达式1,下标表达式2]
数组名[下标表达式1,下标表达式2,…,下标表达式n]
数组的秩(数组的维度)存放在属性Rank中,每一维的长度可以通过GetLength方法
来得到。

维度的最小下标值始终是0,最大下标值可以由该维的。

int[, ,] arr = new int[4, 5, 6];
Console.WriteLine("数组arr的秩是:" + arr.Rank);
Console.WriteLine("第一维的长度是:" + arr.GetLength(0));
Console.WriteLine("第二维的长度是:" + arr.GetLength(1));
Console.WriteLine("第一维的最大下标值:" + arr.GetUpperBound(0));
Console.WriteLine("第二维的最大下标值:" + arr.GetUpperBound(1));
二维数组的遍历:
int[, ] arr = new int[4, 2]{{1,2},{3,4},{5,6},{7,8}};
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.Write("arr[{0},{1}]={2} ", i, j, arr[i, j]);
}
Console.WriteLine();
}
int[, ] arr = new int[4, 2]{{1,2},{3,4},{5,6},{7,8}};
foreach (int i in arr)
{
Console.Write(i + " ");
}
三、数组示例
【例】拼数字游戏。

控件分布图
游戏运行图操作步骤:
(1)在窗体上放置1个Button控件,命名为btnPlay;
(2)在窗体上放置1个Panel控件,Size为“240,240”,BackColor为Silver;
(3)在Panel控件上放置9个Label控件,并按Ctrl键全部选中它们,并将它们的属性设置如下。

(5)双击btnPlay按钮,生成Click事件。

选中所有Label控件,并在事件窗口中双击Click 事件。

代码如下:
Label[,] arrLbl = new Label[3, 3];//存放Label控件的二维数组
int unRow = 0, unCol = 0;//记录不可见Label的下标
bool playing = false; //是否正在游戏中
private void btnPlay_Click(object sender, EventArgs e)
{//把9个Label控件装入二维数组中以方便控件
arrLbl[0, 0] = label1;
arrLbl[0, 1] = label2;
arrLbl[0, 2] = label3;
arrLbl[1, 0] = label4;
arrLbl[1, 1] = label5;
arrLbl[1, 2] = label6;
arrLbl[2, 0] = label7;
arrLbl[2, 1] = label8;
arrLbl[2, 2] = label9;
arrLbl[unRow, unCol].Visible = true;//防止2次单击开始游戏
int[] arrNum = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//将一维数组arrNum中的数字随机排列
Random rm = new Random();//初始化随机函数类
for (int i = 0; i < 8; i++)
{
int rmNum = rm.Next(i, 9);//随机数大于等于i,小于9
int temp = arrNum[i];//交换数组中2个元素的值
arrNum[i] = arrNum[rmNum];
arrNum[rmNum] = temp;
}
for (int i = 0; i < 9; i++)
{//把一维数组的数字依次在二维数组中的标签控件显示
arrLbl[i / 3, i % 3].Text = arrNum[i].ToString();
}
int cover = rm.Next(0, 9);//生成一个随机数用于掩盖某个数字
unRow = cover / 3;//转化为不可见标签的在二维数组中的行下标
unCol = cover % 3;//转化为列下标
arrLbl[unRow, unCol].Visible = false;//让这个标签不可见
playing = true;//设置游戏进行中标记
}
private void Label1_Click(object sender, EventArgs e)
{
if (!playing)//如果游戏不在进行中
{
return;//退出事件方法的执行
}
int row = ((Label)sender).Top / 80;//计算点中标签的行下标
int col = ((Label)sender).Left / 80;//计算点标签的列下标
if (Math.Abs(row - unRow) + Math.Abs(col - unCol) == 1)
{//判断方块是否可以移动,如果可以则交换标签显示的数字
string temp = arrLbl[unRow, unCol].Text;
arrLbl[unRow, unCol].Text = arrLbl[row, col].Text;
arrLbl[row, col].Text = temp;
arrLbl[unRow, unCol].Visible = true;
arrLbl[row, col].Visible = false;
unRow = row;//设置新的不可见标签下标值
unCol = col;
}
for (int i = 0; i < 9; i++)
{//判断是否已成功排列数字
if (arrLbl[i / 3, i % 3].Text != Convert.ToString(i + 1)) {
break;
}
if (i == 8)
{
arrLbl[unRow, unCol].Visible = true;//显示被掩盖数字 playing = false;//设置游戏结束标志
MessageBox.Show("恭喜你通过了游戏!","消息对话框
",MessageBoxButtons .OK ,rmation );
}
}
}
四、动态数组
所谓动态数组就是在程序运行时,可以动态地改变数组的长度,前面介绍的Array一旦确定其长度,便不能再更改。

在C#中并没有真正意义上的动态数组,如果需要在程序中动态地改变数组的长度,可以使用ArrayList作为替代品。

使用ArrayList必须引用:using System.collections;
1.ArrayList的声明与创建
ArrayList arr=new ArrayList();
ArrayList arr1=new ArrayList(10);
ArrayList arrList = new ArrayList(5);
Console.WriteLine("ArrayList的长度为:"+arrList .Count );
int[] arr = new int[5];
Console.WriteLine("数组的长度为:" + arr.Length);
foreach (int i in arr)
{
Console.Write(i + " ");
}
2.ArrayList的操作
Add()方法:
ArrayList arrList = new ArrayList(5);
arrList.Add(100);
arrList.Add(200);
arrList[0] = 1;
Console.WriteLine(arrList[0] + " " + arrList[1]);
Insert()方法:
ArrayList arrList = new ArrayList(5);
arrList.Add(100);
arrList.Add(300);
foreach (int i in arrList)
{
Console.Write(i + " ");
}
arrList.Insert(1, 200);
Console.WriteLine();
foreach (int i in arrList)
{
Console.Write(i + " ");
}
Remove()方法:
ArrayList arrList = new ArrayList(5);
arrList.Add(100);
arrList.Add(200);
arrList.Add(300);
arrList.Add(200);
foreach (int i in arrList)
{
Console.Write(i + " ");
}
arrList.Remove (200);
Console.WriteLine();
foreach (int i in arrList)
{
Console.Write(i + " ");
}
RemoveAt()方法:
ArrayList arrList = new ArrayList(5);
arrList.Add(100);
arrList.Add(200);
arrList.Add(300);
arrList.Add(400);
foreach (int i in arrList)
{
Console.Write(i + " ");
}
//arrList.RemoveAt (1);
arrList.RemoveRange(1, 2);
Console.WriteLine();
foreach (int i in arrList)
{
Console.Write(i + " ");
}
Array和ArrayList的区别:
(1)Array的容量是固定的,而ArrayList的容量可根据需要自动扩充;
(2)ArrayList提供添加、插入或移除某一范围元素的方法。

在Array中,只能一次获取或设置一个元素的值。

(3)Array可以具有多个维度,而ArrayList始终只是一维的。

五、锯齿数组
锯齿数组,也叫做数组的数组,或不规则数组。

int[][] jagged = new int[3][];
jagged[0] = new int[2] { 1, 2 };
jagged[1] = new int[6] { 3, 4, 5, 6, 7, 8 };
jagged[2] = new int[3] { 9, 10, 11 };
for (int row = 0; row < jagged.Length; row++)
{
for (int element = 0; element < jagged[row].Length; element++) {
Console.Write(jagged[row][element]+" ");
}
Console.WriteLine();
}
六、实训练习
实训项目:拼图游戏。

游戏运行图
控件布置图
操作步骤:
(1)在窗体上放置1个Button控件,命名为btnPlay;
(2)在窗体上放置1个Panel控件,Size为“240,240”,BackColor为Silver;
(3)在窗体上放置一个ImageList控件,ImageSize为“80,80”,单击集合小按钮添加9个小图片。

(4)双击窗体生成窗体的Load事件方法,双击btnPlay按钮按钮的Click事件方法。

并打开代码窗口,输入代码如下:
Label[,] arrLbl = new Label[3, 3];//存放Label控件的二维数组
int unRow = 0,unCol=0;//记录不可见Label的下标
bool playing=false ;//是否正在游戏中
private void MainForm_Load(object sender, EventArgs e)
{//动态地加载Label控件
this.SuspendLayout ();//停止layout事件,防止添加控件时多次刷新窗体
for(int i=0;i<3;i++)
{//用双重循环一个一个地添加Label控件
for(int j=0;j<3;j++)
{
Label lbl=new Label ();//新建一个Label控件
lbl.Text ="";//设置控件属性
lbl .AutoSize =false ;
lbl.Size =new Size (80,80);//大小
lbl .Location =new Point (j*80,i*80);//位置
lbl .ImageList =imageList1 ;//指定图像集合控件
//下面这句代码演示如何手动地给控件指定一个事件方法
lbl .Click+=new System.EventHandler (this.lblPic_Click);
panel1 .Controls .Add (lbl);//把标签添加进panel控件内
arrLbl [i,j]=lbl;//把标签添加进二维数组内
}
}
this.ResumeLayout ();//重新启动Layout事件
}
private void btnPlay_Click(object sender, EventArgs e)
{//开始游戏
arrLbl[unRow, unCol].Visible = true;
int[] arrNum = { 0,1, 2, 3, 4, 5, 6, 7, 8 };
Random rm = new Random();
for (int i = 0; i < 8; i++)
{
int rmNum = rm.Next(i, 9);
int temp = arrNum[i];
arrNum[i] = arrNum[rmNum];
arrNum[rmNum] = temp;
}
for (int i = 0; i < 9; i++)
{//通过设置ImageIndex属性,给Label控件指定一个索引号来显示ImageList 内的相应图片
arrLbl[i / 3, i % 3].ImageIndex = arrNum[i];
arrLbl[i / 3, i % 3].BorderStyle = BorderStyle.FixedSingle;
}
int cover = rm.Next(0, 9);
unRow = cover / 3;
unCol = cover % 3;
arrLbl[unRow, unCol].Visible = false;
playing = true;
}
//注意,下面代码需要手动生成,用于给前面动态生成的事件指定方法
private void lblPic_Click(object sender, EventArgs e)
{
if (!playing)
{
return;
}
int row = ((Label)sender).Top / 80;
int col = ((Label)sender).Left / 80;
if (Math.Abs(row - unRow) + Math.Abs(col - unCol) == 1)
{//交换图片索引号以达到交换图片的目的
int temp = arrLbl[unRow, unCol].ImageIndex ;
arrLbl[unRow, unCol].ImageIndex = arrLbl[row, col].ImageIndex ;
arrLbl[row, col].ImageIndex = temp;
arrLbl[unRow, unCol].Visible = true;
arrLbl[row, col].Visible = false;
unRow = row;
unCol = col;
}
for (int i = 0; i < 9; i++)
{
if (arrLbl[i / 3, i % 3].ImageIndex != i)
{
break;
}
if (i == 8)
{
arrLbl[unRow, unCol].Visible = true;
foreach (Label lbl in arrLbl )
{
lbl.BorderStyle =BorderStyle .None ;
}
playing = false;
MessageBox.Show("恭喜你通过了游戏!", "消息对话框", MessageBoxButtons.OK, rmation);
}
}
}
作业:
1.编写程序,从键盘中输入10个数据存入数组中,找出数组中的最大值。

2.定义一个大小为10的整型数组,用随机产生的数据为数组元素赋值,并将它们按从大到小排序输出(使用选择法进行排序)。

相关文档
最新文档