C#成神之路<12> C#数组
发布日期:2021-05-07 18:45:01 浏览次数:20 分类:原创文章

本文共 19548 字,大约阅读时间需要 65 分钟。

1、数组的定义

语法规范:

typeSpecifier[] arrayName=new typeSpecifier [numberOfEleements];

(1)数组元素和数组索引
数组在内存中连续使用n个字节数。
数组索引是数组中特定元素的位置。

(2)N-1规则
数组允许的最高索引比数组元素数量少一。
比如:size=myData.Length;
是对数组大小的检测。

示例程序:字母计数
在文本框中输入几个句子,计算每个字母在文本中出现的次数,不需要关注标点符号空格数字和大小写。

using System;using System.Windows.Forms;public class frmMain : Form{    private const int MAXLETTERS = 26;    private const int MAXCHAR = MAXLETTERS - 1;    private const int LETTER = 65;    private Label label1;    private TextBox txtInput;    private Button btnCalc;    private Button btnClose;    private Label label2;    private Label label3;    private ListBox lstOutput;    #region Windows code    private void InitializeComponent()    {            this.label1 = new System.Windows.Forms.Label();            this.txtInput = new System.Windows.Forms.TextBox();            this.btnCalc = new System.Windows.Forms.Button();            this.btnClose = new System.Windows.Forms.Button();            this.label2 = new System.Windows.Forms.Label();            this.label3 = new System.Windows.Forms.Label();            this.lstOutput = new System.Windows.Forms.ListBox();            this.SuspendLayout();            //             // label1            //             this.label1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;            this.label1.Location = new System.Drawing.Point(38, 24);            this.label1.Name = "label1";            this.label1.Size = new System.Drawing.Size(473, 23);            this.label1.TabIndex = 0;            this.label1.Text = "Enter letters";            this.label1.TextAlign = System.Drawing.ContentAlignment.TopCenter;            //             // txtInput            //             this.txtInput.BackColor = System.Drawing.Color.White;            this.txtInput.Location = new System.Drawing.Point(38, 65);            this.txtInput.Multiline = true;            this.txtInput.Name = "txtInput";            this.txtInput.Size = new System.Drawing.Size(473, 116);            this.txtInput.TabIndex = 1;            //             // btnCalc            //             this.btnCalc.Location = new System.Drawing.Point(38, 205);            this.btnCalc.Name = "btnCalc";            this.btnCalc.Size = new System.Drawing.Size(120, 23);            this.btnCalc.TabIndex = 2;            this.btnCalc.Text = "Calculate";            this.btnCalc.UseVisualStyleBackColor = true;            this.btnCalc.Click += new System.EventHandler(this.btnCalc_Click);            //             // btnClose            //             this.btnClose.Location = new System.Drawing.Point(384, 205);            this.btnClose.Name = "btnClose";            this.btnClose.Size = new System.Drawing.Size(127, 23);            this.btnClose.TabIndex = 3;            this.btnClose.Text = "Close";            this.btnClose.UseVisualStyleBackColor = true;            this.btnClose.Click += new System.EventHandler(this.btnClose_Click);            //             // label2            //             this.label2.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;            this.label2.Location = new System.Drawing.Point(38, 252);            this.label2.Name = "label2";            this.label2.Size = new System.Drawing.Size(120, 23);            this.label2.TabIndex = 4;            this.label2.Text = "Letter";            this.label2.TextAlign = System.Drawing.ContentAlignment.TopCenter;            //             // label3            //             this.label3.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;            this.label3.Location = new System.Drawing.Point(384, 252);            this.label3.Name = "label3";            this.label3.Size = new System.Drawing.Size(127, 23);            this.label3.TabIndex = 5;            this.label3.Text = "Count";            this.label3.TextAlign = System.Drawing.ContentAlignment.TopCenter;            //             // lstOutput            //             this.lstOutput.FormattingEnabled = true;            this.lstOutput.ItemHeight = 12;            this.lstOutput.Location = new System.Drawing.Point(38, 295);            this.lstOutput.Name = "lstOutput";            this.lstOutput.Size = new System.Drawing.Size(473, 172);            this.lstOutput.TabIndex = 6;            //             // frmMain            //             this.ClientSize = new System.Drawing.Size(543, 510);            this.Controls.Add(this.lstOutput);            this.Controls.Add(this.label3);            this.Controls.Add(this.label2);            this.Controls.Add(this.btnClose);            this.Controls.Add(this.btnCalc);            this.Controls.Add(this.txtInput);            this.Controls.Add(this.label1);            this.Name = "frmMain";            this.Text = "Count Letter";            this.ResumeLayout(false);            this.PerformLayout();    }    #endregion    //#region是C# 预处理器指令。     //#region 使您可以在使用 Visual Studio    //代码编辑器的大纲显示功能时指定可展开或折叠的代码块。    public frmMain()    {        InitializeComponent();    }    public static void Main()    {        frmMain main = new frmMain();        Application.Run(main);    }    private void btnCalc_Click(object sender, EventArgs e)    {        char oneLetter;        int index;        int i;        int length;        int[] count =new int [MAXLETTERS];        string input;        string buff;        length = txtInput.Text.Length;        if (length == 0)        {            MessageBox.Show("You need to enter some letter","Missing input",MessageBoxButtons.OK,MessageBoxIcon.Stop);            txtInput.Focus();            return;        }        input = txtInput.Text;        input = input.ToUpper();        for (i = 0; i < input.Length; i++)        {            oneLetter = input[i];            index = oneLetter - LETTER;            if (index < 0 || index > MAXCHAR)                continue;            count[index]++;         }        for (i = 0; i < MAXLETTERS; i++)        {            buff = string.Format("{0,4}{1,20}[{2}]",(char)(i+LETTER)," ",count[i]);            lstOutput.Items.Add(buff);        }    }    private void btnClose_Click(object sender, EventArgs e)    {        Close();    }}

这里使用了ASCII码进行相关的变换。符号常量LETTER是大写字母A的ASC值。把文本字母换算成数字利用asc可以轻松做到。
如果asc值不在大写字母的范围内,循环中的continue直接跳过后面的语句,进行下一次循环。

(3)ListView对象
功能:格式化列表框中的数据列。使得表格化更加专业。
ListView的重要属性:
View属性:设置为Detail,可以看到修改对象属性所产生的效果。
Columns:创建列表的表头。add之后可以修改表头信息(text)和大小(width)。

     /* for (i = 0; i < MAXLETTERS; i++)        {            buff = string.Format("{0,4}{1,20}[{2}]",(char)(i+LETTER)," ",count[i]);            lstOutput.Items.Add(buff);        }*/        ListViewItem which;        for(i=0;i<MAXLETTERS;i++)        {            oneLetter = (char)(i + LETTER);            which = new ListViewItem(oneLetter.ToString());            which.SubItems.Add(count[i].ToString());            lsvOutput.Items.Add(which);          }

将上面的程序相应位置修改成下式。
第一个语句创建一个ListView引用变量。可将ListViewItem对象看做一组定义一行listview对象的数据。
第四个语句构造函数的方法创建一个ListViewItem对象,使用char对象的Tostring方法将oneLetter转换成一个字符串。并且把创建名为which的ListViemItem的第一列初始化为当前字母。
第五语句,将当前字母的字数存储在count数组中,并且添加到which的ListViewItem中。which包含着名为SubItem的对象。并且使用该对象Add()方法向第一列的数据中添加这个列数据。
最后一句,传递给listview框ListViewItem相关的属性which。完成表格的创建。

2、数组是对象
在C#中数组是对象,意味着数组对象有一组可以使用的属性和方法。所有数组对象都派生自System.Array类。
(1)数组的相关方法
System.Array.BinarySearch(count,target);在名为count的一维数组中进行二分搜索,查找target。
System.Array.Clear(count,start,count.Length);将值类型数组从元素start到元素Length全部清零。引用数组将会被清理为null。
System.Array.Copy(Souce,Dest,Length);将source数组中的length元素拷贝到dest当中。
System.Array.IndexOf(count,val);返回count数组当中第一次出现val的索引。
System.Array.LastIndexOf(count,val);返回count数组最后一次出现val的索引。
System.Array.Sort(count);将名为count的数组进行升序排序。
System.Array.Reserve(count);将名为count的数组翻转。
count.Rank;返回名为count的数组的维度。
count.GetUpperBound(val);返回count数组的维数val的最大索引数量。二维度组使用0和1,应用n-1规则。
count.Initialize();调用构造函数来设置每个元素。

3、多维数组

语法规则:

int[,] grades=new int[5,4];

以上定义方法代表了一个具有五行四列的表或者矩阵。
因为有两个维度,所以该数组的rank(秩)为2。(线性代数相关知识)即与数组关联的维度。
还可以定义三维数组,即一个数据立方。而不是一个列表。

int[,,] images=new int [20,100,200];

应用:游戏软件三个维度来表示三个轴向。利用第四维度来追踪 每个图像应该出现的时间。

示例程序:
功能:输入列表中的行数,显示数字,数字平方和数字立方。
分析:需要一个二维数组。其中一个维度是用户定义的行数,另一个维度具有三个列。
代码:

using System;using System.Windows.Forms;public class frmMain : Form{    private Label label1;    private TextBox txtMax;    private Button btnCalc;    private Button btnClose;    private ListView lsvTable;    private ColumnHeader columnHeader1;    private ColumnHeader columnHeader2;    private ColumnHeader columnHeader3;    #region Windows code    private void InitializeComponent()    {            this.label1 = new System.Windows.Forms.Label();            this.txtMax = new System.Windows.Forms.TextBox();            this.btnCalc = new System.Windows.Forms.Button();            this.btnClose = new System.Windows.Forms.Button();            this.lsvTable = new System.Windows.Forms.ListView();            this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));            this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));            this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));            this.SuspendLayout();            //             // label1            //             this.label1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;            this.label1.Location = new System.Drawing.Point(30, 21);            this.label1.Name = "label1";            this.label1.Size = new System.Drawing.Size(117, 23);            this.label1.TabIndex = 0;            this.label1.Text = "Input the number";            this.label1.TextAlign = System.Drawing.ContentAlignment.TopRight;            //             // txtMax            //             this.txtMax.Location = new System.Drawing.Point(153, 19);            this.txtMax.Name = "txtMax";            this.txtMax.Size = new System.Drawing.Size(159, 21);            this.txtMax.TabIndex = 1;            //             // btnCalc            //             this.btnCalc.Location = new System.Drawing.Point(30, 62);            this.btnCalc.Name = "btnCalc";            this.btnCalc.Size = new System.Drawing.Size(75, 23);            this.btnCalc.TabIndex = 2;            this.btnCalc.Text = "Calculate";            this.btnCalc.UseVisualStyleBackColor = true;            this.btnCalc.Click += new System.EventHandler(this.btnCalc_Click);            //             // btnClose            //             this.btnClose.Location = new System.Drawing.Point(237, 62);            this.btnClose.Name = "btnClose";            this.btnClose.Size = new System.Drawing.Size(75, 23);            this.btnClose.TabIndex = 3;            this.btnClose.Text = "Close";            this.btnClose.UseVisualStyleBackColor = true;            this.btnClose.Click += new System.EventHandler(this.btnClose_Click);            //             // lsvTable            //             this.lsvTable.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {            this.columnHeader1,            this.columnHeader2,            this.columnHeader3});            this.lsvTable.Location = new System.Drawing.Point(30, 91);            this.lsvTable.Name = "lsvTable";            this.lsvTable.Size = new System.Drawing.Size(282, 207);            this.lsvTable.TabIndex = 4;            this.lsvTable.UseCompatibleStateImageBehavior = false;            this.lsvTable.View = System.Windows.Forms.View.Details;            //             // columnHeader1            //             this.columnHeader1.Text = "N";            this.columnHeader1.Width = 85;            //             // columnHeader2            //             this.columnHeader2.Text = "N*N";            this.columnHeader2.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;            this.columnHeader2.Width = 93;            //             // columnHeader3            //             this.columnHeader3.Text = "N*N*N";            this.columnHeader3.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;            this.columnHeader3.Width = 93;            //             // frmMain            //             this.ClientSize = new System.Drawing.Size(351, 329);            this.Controls.Add(this.lsvTable);            this.Controls.Add(this.btnClose);            this.Controls.Add(this.btnCalc);            this.Controls.Add(this.txtMax);            this.Controls.Add(this.label1);            this.Name = "frmMain";            this.ResumeLayout(false);            this.PerformLayout();    }    #endregion    //#region是C# 预处理器指令。     //#region 使您可以在使用 Visual Studio    //代码编辑器的大纲显示功能时指定可展开或折叠的代码块。    public frmMain()    {        InitializeComponent();    }    public static void Main()    {        frmMain main = new frmMain();        Application.Run(main);    }    private void btnCalc_Click(object sender, EventArgs e)    {        bool flag;        int number;        int i;        ListViewItem which;        flag = int.TryParse(txtMax.Text,out number);        if (flag == false)        {            MessageBox.Show("Numeric data only","Input error",MessageBoxButtons.OK                ,MessageBoxIcon.Stop);            txtMax.Focus();            return;        }        if (number < 0)        {            number = number * (-1);        }        number++;//because of the rule of N-1        int[,] myData = new int[number, 3];        for (i = 0; i < number; i++)        {            myData[i, 0] = i;            myData[i, 1] = i * i;            myData[i, 2] = i * i * i;        }        for (i = 0; i < number; i++)        {            which = new ListViewItem(myData[i,0].ToString());            which.SubItems.Add(myData[i,1].ToString());            which.SubItems.Add(myData[i,2].ToString());            lsvTable.Items.Add(which);        }    }    private void btnClose_Click(object sender, EventArgs e)    {        Close();    }}

以上程序的两个for循环没有合并的原因:通过利用RDC代码来减轻代码的忙碌程度。当然也可以完全抛弃第二个for,但是这样连数组也抛弃了。为了便于说明数组的优势,采用两个for循环。

4、初始化数组
C#提供一种更加方便的初始化数组方式:

typeSpecifier[] arrayID=new typeSpecifier[elementCount]{val1,val2,val3};

变体:可以不必填写数组的元素数量,或者省略new int[]也可以。
(三种方式都可以我拿成任务,重要的是对所使用的选项保持一致性)

初始化多维数组的方式:

typeSpecifier[,] arrayID=new typeSpecifier[ab]{   {   val1,val2,val3},{   val4,val5,val6}};

对象的初始化列表:
与值类型数据的语法相同。对象的数组的工作方式与值类型数据的工作方式不完全相同。
lvalue存储连续内存地址的数组。rvalue是包含指向存储他数据的内存地址。
对象数组缺少对称性,即“不规则数组”,所以采用以上机制。
同时在运行时可以定义不规则数组,只有多维数组的最后一个维度可以是未指定的。

5、集合
集合是一组拥有相同特征的对象。

private void btnCalc_Click(Object sender,EventArgs e){int days=new int[]{  0,31,28,31,30,31,30,31,31,30,31,31}string weekDays=new string[] {  "Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};foreach(string str in weekDays){lstTest.Items.Add(str);}foreach(int val in days){lstTest.Items.Add(val);}}

注意其中的foreach循环。类似于for循环,但是for的第一个表达式的内容总是设置成集合中的第一个对象。并且循环逐个遍历数组中所有的元素。循环中使用的数据类型必须与集合中的数据类型相匹配。并且,foreach循环为只读循环,不能再该循环中试图修改对象。

6、ArrayList 对象

ArrayList对象是动态数组,可以避免静态数组当中效率低下的估值局限性。
示例程序:
实现功能:允许向列表中添加一个人的姓名。而用户对要添加多少个姓名并没有概念。
分析:利用ArrayList的动态数组的功能完成程序编写。
代码:

using System;using System.Windows.Forms;using System.Collections;public class frmMain : Form{    ArrayList names = new ArrayList();    private Label label1;    private TextBox txtName;    private Button btnAdd;    private Button btnShow;    private Button btnClose;    private ListBox lstNames;    #region Windows code    private void InitializeComponent()    {            this.label1 = new System.Windows.Forms.Label();            this.txtName = new System.Windows.Forms.TextBox();            this.btnAdd = new System.Windows.Forms.Button();            this.btnShow = new System.Windows.Forms.Button();            this.btnClose = new System.Windows.Forms.Button();            this.lstNames = new System.Windows.Forms.ListBox();            this.SuspendLayout();            //             // label1            //             this.label1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;            this.label1.Location = new System.Drawing.Point(33, 33);            this.label1.Name = "label1";            this.label1.Size = new System.Drawing.Size(117, 23);            this.label1.TabIndex = 0;            this.label1.Text = "Enter the name";            this.label1.TextAlign = System.Drawing.ContentAlignment.TopRight;            //             // txtName            //             this.txtName.Location = new System.Drawing.Point(165, 35);            this.txtName.Name = "txtName";            this.txtName.Size = new System.Drawing.Size(159, 21);            this.txtName.TabIndex = 1;            //             // btnAdd            //             this.btnAdd.Location = new System.Drawing.Point(33, 90);            this.btnAdd.Name = "btnAdd";            this.btnAdd.Size = new System.Drawing.Size(75, 23);            this.btnAdd.TabIndex = 2;            this.btnAdd.Text = "Add";            this.btnAdd.UseVisualStyleBackColor = true;            this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);            //             // btnShow            //             this.btnShow.Location = new System.Drawing.Point(138, 90);            this.btnShow.Name = "btnShow";            this.btnShow.Size = new System.Drawing.Size(75, 23);            this.btnShow.TabIndex = 3;            this.btnShow.Text = "Show";            this.btnShow.UseVisualStyleBackColor = true;            this.btnShow.Click += new System.EventHandler(this.btnShow_Click);            //             // btnClose            //             this.btnClose.Location = new System.Drawing.Point(249, 90);            this.btnClose.Name = "btnClose";            this.btnClose.Size = new System.Drawing.Size(75, 23);            this.btnClose.TabIndex = 4;            this.btnClose.Text = "Close";            this.btnClose.UseVisualStyleBackColor = true;            this.btnClose.Click += new System.EventHandler(this.btnClose_Click);            //             // lstNames            //             this.lstNames.FormattingEnabled = true;            this.lstNames.ItemHeight = 12;            this.lstNames.Location = new System.Drawing.Point(33, 139);            this.lstNames.Name = "lstNames";            this.lstNames.Size = new System.Drawing.Size(291, 220);            this.lstNames.TabIndex = 5;            //             // frmMain            //             this.ClientSize = new System.Drawing.Size(365, 424);            this.Controls.Add(this.lstNames);            this.Controls.Add(this.btnClose);            this.Controls.Add(this.btnShow);            this.Controls.Add(this.btnAdd);            this.Controls.Add(this.txtName);            this.Controls.Add(this.label1);            this.Name = "frmMain";            this.Text = "Use ArrayList";            this.ResumeLayout(false);            this.PerformLayout();    }    #endregion    //#region是C# 预处理器指令。     //#region 使您可以在使用 Visual Studio    //代码编辑器的大纲显示功能时指定可展开或折叠的代码块。    public frmMain()    {        InitializeComponent();    }    public static void Main()    {        frmMain main = new frmMain();        Application.Run(main);    }    private void btnAdd_Click(object sender, EventArgs e)    {        if (txtName.Text.Length != 0)        {            names.Add(txtName.Text);            txtName.Clear();            txtName.Focus();        }        else        {            MessageBox.Show("Please input a name","input error",MessageBoxButtons.OK,MessageBoxIcon.Stop);            return;        }    }    private void btnShow_Click(object sender, EventArgs e)    {        foreach (string str in names)        {            lstNames.Items.Add(str);        }    }    private void btnClose_Click(object sender, EventArgs e)    {        Close();    }}

注意,在使用动态数组的时候,要添加新的using内容:System.Collection;
在默认情况下没有包括在程序中。ArrayList属性和方法和数组的方法属性大致相同。

动态数组的缺点:
动态数组会比相同对象的静态数组占用更多的内存。会对性能产生一定的影响。

上一篇:C#成神之路<13> C#对类的设计
下一篇:C#成神之路<11> C#循环重复语句

发表评论

最新留言

感谢大佬
[***.8.128.20]2025年04月05日 17时05分45秒