C#基本数据结构-数组

文章目录

    • 一维数组的声明和使用
    • 二维维数组的声明和使用
      • 动态二维数组的声明及使用
    • 特殊数组
      • 多维数组
      • 交错数组
    • 传递数组给函数
    • 参数数组
    • 对Array类的使用
      • Array类的属性及方法
      • 遍历数组
      • 查找数组元素
      • 数组排序
      • 数组合并与拆分

一维数组的声明和使用

C#声明数组时,方括号[]必须跟在类型后面,而不是标识符后面。

  1. 声明一维数组
    C#数组的大小不是其类型的一部分,而在C语言中却是数组类型的一部分。
  2. 初始化一维数组
    声明一个数组不会在内存中初始化数组。当初始化数组变量时,用户可以赋值给数组。数组是一个引用类型,所以C#数组的初始化方式有一下两种:
    (1) 第一种是在声明数组的时候为数组的元素赋初值。
    (2) 另一种方式需要在声明数组时指定数组的大小(即数组的长度,数组元素的个数),这种方式需要使用new关键字来创建数组的实例。
  3. 为一维数组赋值
    (1) 可以通过使用索引号赋值给一个单独的数组元素。
    (2) 可以在声明数组的同时给数组赋值。
    (3) 可以创建并初始化一个数组。
    当用户创建一个数组时,C#编译器会根据数组类型隐式初始化每个数组元素为一个默认值。例如,int数组的所有元素都会被初始化为0。
    元素是通过带索引的数组名称来访问的。就是将元素的索引放置在数组名称后的方括号中来实现的。
    编写程序声明一个数组,并对其进行赋值和访问操作
using System;
namespace Project1
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] a = new int[5]; /* a 是一个带有 5 个整数的数组 */
            int i, j;    /*表示循环变量 */
            /* 初始化数组 a 中的元素 */
            for (i = 0; i < 5; i++)
            {
                a[i] = i + 50;
            }
            /* 输出每个数组元素的值 */
            for (j = 0; j < 5; j++)
            {
                Console.WriteLine("第[{0}]个元素是: = {1}", j, a[j]);
            }
            Console.WriteLine("数组长度为:{0}", a.Length);
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示一维数组的赋值与访问。在代码中,首先,声明一个int类型的数组a,并使用new关键字为其分配5个内存空间;接着再定义两个整型变量i和j,用于表示循环变量;然后,使用for循环为数组a初始化赋值;最后,再使用for循环和数组元素对应的下标来访问数组中的元素。

[0]个元素是: = 50[1]个元素是: = 51[2]个元素是: = 52[3]个元素是: = 53[4]个元素是: = 54
数组长度为:5

二维维数组的声明和使用

前面介绍的数组只有一个下标,称为一维数组,其数组元素也称为单下标变量。在实际问题中有很多量是二维的或多维的,因此C#允许构造多维数组。多维数组元素有多个下标,以标识它在数组中的位置,所以也称为多下标变量。

  1. 声明二维数组
    二维数组的语法格式如下:
    datatype[,] arrayName;
    其中,datatype用于表示二维数组存储数据的类型,arryName用于表示二维数组名。
  2. 初始化二维数组
    二维数组的初始化有以下两种形式:
    (1) 第一种是在声明数组的时候为数组的元素赋初值。
    (2) 另一种可以通过new运算符创建数组并将数组元素初始化为它们的默认值。
  3. 二维数组的存储形式
    C#的二维数组,在本质上,是一个一维数组的列表。一个二维数组可以被认为是一个带有i行和j列的表格。
  4. 二维数组的赋值
    二维数组可以通过在括号内为每行指定值来进行赋值。
using System;
namespace Project3
{
    class Program
    {
        static void Main(string[] args)
        {
            /* 一个带有 34 列的数组 */
            int[,] a = new int[3, 4] {
                {0, 1, 2, 3} ,
                {4, 5, 6, 7} ,
                {8, 9, 10, 11}
            };
            int i, j;
            /* 输出数组中每个元素的值 */
            for (i = 0; i < 3; i++)
            {
                for (j = 0; j < 4; j++)
                {
                    Console.Write("a[{0},{1}] = {2}\t", i, j, a[i, j]);
                }
                Console.WriteLine();
            }
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示二维数组的遍历。在代码中,首先声明一个二维数组a,并使用new关键字为其分配空间,接着对它进行初始化;然后再定义两个整型变量i和j,用于表示二维数组的行和列;最后,通过嵌套的for循环输出该二维数组。

a[0,0] = 0      a[0,1] = 1      a[0,2] = 2      a[0,3] = 3
a[1,0] = 4      a[1,1] = 5      a[1,2] = 6      a[1,3] = 7
a[2,0] = 8      a[2,1] = 9      a[2,2] = 10     a[2,3] = 11

动态二维数组的声明及使用

所谓动态数组,就是指程序在运行过程中将数组的定义部分和初始化部分分别写在不同的语句中。动态数组的初始化也需要使用关键字new为数组元素分配内存空间,并为数组元素赋初值。
C#基本数据结构-数组_第1张图片

using System;
namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("请输入动态数组的行数:");
            int x = Convert.ToInt32(Console.ReadLine());  //定义x表示行数
            Console.Write("请输入动态数组的列数:");
            int y = Convert.ToInt32(Console.ReadLine());  //定义y表示列数
            int[,] arr = new int[x, y];   //定义数组arr,使用new关键字分配x行y列的空间
            Console.WriteLine("遍历数组arr:");
            for (int i = 0; i < x; i++)   //遍历行元素
            {
                for (int j = 0; j < y; j++)  //遍历列元素
                {
                    Console.Write(i + j.ToString() + " ");  //" "是空格
                }
                Console.ReadLine();
            }
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示了动态二维数组的使用。在代码中,首先定义两个整型变量x和y,分别用于表示行数和列数;然后将键盘上输入的数据转换为整型数据并赋给变量x和y,这样就得到了行数和列数的确定值;接着使用关键字new为数组arr分配x行y列的空间;最后通过for循环将数组的行索引和列索引以字符串的形式合并在一起,作为动态二维数组的元素值输出。

请输入动态数组的行数:5
请输入动态数组的列数:4
遍历数组arr:
00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33
40 41 42 43

特殊数组

多维数组

在C#中声明多维数组,需要在方括号中加上逗号。数组在初始化时应指定每一维度的大小。
编写程序,使用for语句遍历一个三维数组。

using System;
namespace test
{
    class Program
    {
        static void Main()
        {
            int[,,] a;              //定义一个三维数组a,并为其赋值
            a = new int[,,] {
                { { 1, 2 }, { 3, 4 } },
                { { 5, 6 }, { 7, 8 } },
                { { 9, 10 }, { 11, 12 } }
            };
            int i, j, k;
            for (i = 0; i < 3; i++)   //索引纵深
            {
                for (j = 0; j < 2; j++)    //索引行数
                {
                    for (k = 0; k < 2; k++)   //索引列数
                    {
                        Console.Write("a[{0}][{1}][{2}]={3}\t", i, j, k, a[i, j, k]);
                    }
                    Console.WriteLine();
                }
                Console.WriteLine();
            }
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示了三维数组的输出。在代码中,首先声明一个三维数组a,并使用new关键字为其分配空间,接着将其初始化为2行2列3纵深的三维数组,然后再定义三个循环变量i,j,k,最后使用三层嵌套的for循环遍历出数组a中的元素。

a[0][0][0]=1    a[0][0][1]=2
a[0][1][0]=3    a[0][1][1]=4

a[1][0][0]=5    a[1][0][1]=6
a[1][1][0]=7    a[1][1][1]=8

a[2][0][0]=9    a[2][0][1]=10
a[2][1][0]=11   a[2][1][1]=12

交错数组

交错数组也称锯齿形数组,是一种不规则的二维数组,它与矩形数组(二维数组)最大的差异,在于数组中每一行的长度并不相同,可以把它想象成有不同长度的一维数组组合而成的矩形数组,所以交错数组也被称为“数组中的数组”,它比矩形数组更加节省内存空间,当然同时也要在创建和使用时按照其特点进行操作。
编写程序,遍历出交错数组

using System;
class MyClass
{
    static void Main()
    {
        int[][] arr = new int[4][];
        arr[0] = new int[] { 1, 3, 5, 32 };
        arr[1] = new int[] { 2, 10 };
        arr[2] = new int[] { 8, 7, 25, 6 };
        arr[3] = new int[] { 9, 4, 0, 11, 5 };
        foreach (int[] i in arr)
        {
            foreach (int j in i)
            {
                Console.Write("{0}  ", j);
            }
            Console.WriteLine();
        }
        Console.ReadKey();
    }
}

程序分析】本例演示了交错数组的遍历。在Main方法中,用户自定义一个不规则的二维数组arr,然后为该数组进行初始化,最后通过foreach循环进行遍历。

1  3  5  32
2  10
8  7  25  6
9  4  0  11  5

传递数组给函数

在C#中,用户可以传递数组作为方法的参数。用户可以通过指定不带索引的数组名称来给函数传递一个指向数组的指针。
编写程序,用户自定义方法getAverage,用于求出一个整型数组的平均值。

using System;
namespace Project8
{
    class Program
    {
        public static  double getAverage(int[] arr, int size)
        {
            int i;
            double avg;
            int sum = 0;
            for (i = 0; i < size; ++i)
            {
                sum += arr[i];
            }
            avg = (double)sum / size;
            return avg;
        }
        static void Main(string[] args)
        {
            Program app = new Program();
            /* 一个带有 5 个元素的 int 数组 */
            int[] arr = new int[] { 29, 32, 43, 17, 50 };
            double avg;
            /* 传递数组的指针作为参数 */
            avg = getAverage(arr, 5);
            /* 输出返回值 */
            Console.WriteLine("平均值是: {0} ", avg);
            Console.ReadKey();
        }
    }
}

程序分析】本例演示了如何传递数组给函数。在代码中,用户首先自定义一个静态的double类型的方法getAverage,该方法的作用是接收从Main方法传递过来的数据进行求和并计算出平均值,最后将平均值作为该方法的返回值。在Main方法中,首先定义一个整型数组arr,并为其初始化赋值,接着将数组名arr作为getAverage方法的实参进行传递。

平均值是: 34.2

params的使用格式为:
在这里插入图片描述

using System;
namespace Project9
{
    class Program
    {
        public static int AddMethod(params int[] arr)
        {
            int sum = 0;
            foreach (int i in arr)
            {
                sum += i;
            }
            return sum;
        }
        static void Main(string[] args)
        {
            int sum = AddMethod(53, 72, 50, 67, 89);
            Console.WriteLine("总和是: {0}", sum);
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示了如何使用参数数组。在代码中,用户首先自定义一个静态的int类型的方法AddMethod,该方法用于计算一个数组中所有元素的和,并将结果作为该方法的返回值。由于是接收一个未知个数的数组,所以将AddMethod方法的形参数组arr,用params进行修饰。在Main方法中,直接对AddMethod方法输入5个实参的值,最后返回这5个数据的和。

总和是: 331

参数数组

有时,当声明一个方法时,用户不能确定要传递给函数作为参数的参数数目。C#参数数组解决了这个问题,参数数组通常用于传递未知数量的参数给函数。参数数组通过关键字params定义。params类型参数主要用于在对数组长度未知的情况下进行函数声明,调用时可以传入个数不同的实参,具有很好的灵活性。

对Array类的使用

C#数组是由System.Array类派生而来的引用对象,可以使用Array类的属性来对数组进行各种操作。

Array类的属性及方法

用方括号声明数组是C#中使用Array类的表示法。在后台使用C#语法,会创建一个派生自抽象基类Array的新类。这样,就可以使用Array类为每个C#数组定义的方法和属性了。

using System;
namespace Project10
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] intArry = new int[5];
            for (int x = 1; x <= 5; x++)
            {
                intArry[x - 1] = x;
            }
            Console.WriteLine("显示数组中的数据");
            for (int i = 1; i <= 5; i++)
            {
                Console.Write("{0} ", intArry[i - 1]);
            }
            Console.WriteLine("\n");
            Console.WriteLine("数组是否带有固定大小:" + intArry.IsFixedSize);
            Console.WriteLine("数组是否只读:" + intArry.IsReadOnly);// 是否只读
            Console.WriteLine("数组的长度:" + intArry.Length);//数组的长度
            Console.WriteLine("数组的长度:" + intArry.LongLength);//数组的长度
            Console.WriteLine("数组的维度:" + intArry.Rank);//数组的维数
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示通过Array类输出数组的相关属性。在代码中,首先定义一个int类型的数组intArry;然后通过for循环为其赋值,并打印出来;最后调用Array类的属性,输出该数组的长度、维度、是否只读,以及是否带有固定大小。

显示数组中的数据
1 2 3 4 5

数组是否带有固定大小:True
数组是否只读:False
数组的长度:5
数组的长度:5
数组的维度:1

C#基本数据结构-数组_第2张图片

遍历数组

using System;
namespace Project11
{
    class Program
    {
        static void Main(string[] args)
        {
            //5行2列
            string[,] Student = { { "张三","2班"}, { "李四", "1班" }, { "王五", "5班" }, { "赵六", "3班" }, { "孙七", "未知" }};
            //正序遍历
            Console.WriteLine("以下是正序输出");
            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    Console.Write(Student[i, j] + "\t");
                }
                Console.WriteLine();
            }
            //倒叙遍历
            Console.WriteLine("以下是倒序输出");
            for (int i = 4; i >= 0; i--)
            {
                for (int j = 1; j >= 0; j--)
                {
                    Console.Write(Student[i, j] + "\t");
                }
                Console.WriteLine();
            }
            Console.WriteLine("以下为Length属性:数组包含元素的总个数");
            Console.WriteLine(Student.Length);
            //获取数组中指定维度的下界
            Console.WriteLine(Student.GetLowerBound(0));
            //获取数组中指定维度的上界
            Console.WriteLine(Student.GetUpperBound(0));
            Console.ReadKey();
        }
    }
}

程序分析】本例演示了如何遍历数组。在代码中,首先定义一个string类型的二维数组Student,并为其初始化赋值;接着通过for循环,进行正序遍历和倒序遍历;然后通过Length属性,获取数组包含元素的总个数;调用GetLowerBound方法,获取数组中指定维度的下界为第0行,再调用GetUpperBound方法,获取数组中指定维度的上界为第4行。

以下是正序输出
张三    2班
李四    1班
王五    5班
赵六    3班
孙七    未知
以下是倒序输出
未知    孙七
3班     赵六
5班     王五
1班     李四
2班     张三
以下为Length属性:数组包含元素的总个数
10
0
4

查找数组元素

查找数组元素可以解决两类问题。第一类可以查看这个数组是否存在某个元素;第二类则可以获取已知存在元素的索引值。
编写程序,查找某数组中某个元素的索引值

using System;
namespace Project12
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] myintArray = { 11, 5, 89, 35, 24, 9, 17, 20, 63, 12, 18, 9, 29, 37, 14 };
            //想查找是否存在某个元素,
            //IndexOf可以查找元素首次出现的位置
            //LastIndexOf 可以查找元素最后一次出现的位置,位置都是以从0开始的索引值
            //IndexOf与LastIndexOf 都返回一个索引值,为int
            int first, last;
            first = Array.IndexOf(myintArray, 9);
            last = Array.LastIndexOf(myintArray, 9);
            //int result;
            IndexOf(参数1,参数2):参数1是我们要查找的数据,参数2是要查找的元素
            //result = 
            //我们常常用返回值来判断某个数组中是否存在某个元素,
            //如果存在则返回一个索引值,否则返回-1
            if (first < 0)
            {
                Console.WriteLine("未找到元素9");
            }
            else
            {
                Console.WriteLine("找到元素9");
            }
            Console.WriteLine("该元素第一次出现的索引值是:{0}, 最后一次出现的索引值是:{1}",Array.IndexOf(myintArray,9),Array.LastIndexOf(myintArray,9));
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示了如何查找数组中的元素。在代码中,定义int类型的数组myintArray并初始化赋值。IndexOf方法可以查找元素首次出现的位置,而LastIndexOf方法则可以查找元素最后一次出现的位置,元素的位置都是从0开始的索引值。这里需要注意,IndexOf与LastIndexOf方法都有两个参数,第一个参数是用户要查找的数据,第二个参数是要查找的元素,并且它们都返回一个int类型的索引值。在使用if语句判断时,如果要查找的元素不存在,则IndexOf和LastIndexOf方法会返回-1。

找到元素9
该元素第一次出现的索引值是:5, 最后一次出现的索引值是:11
using System;
namespace Project13
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] myintArray = { 11, 5, 89,  17, 20, 63, 12, 18, 9, 29, 37, 14 };
            Console.WriteLine("原数组是:");
            foreach (int outin in myintArray)
            {
                Console.Write(outin+"  ");
            }
            //利用Sort实现升序的排序,并且更改原数组的存储位置
            Console.WriteLine("\n数组实现升序后是:");
            Array.Sort(myintArray);
            foreach (int outint in myintArray)
            {
                Console.Write(outint + "  ");
            }
            //利用Reverse实现降序的排序,并且更改原数组的存储位置
            Console.WriteLine("\n数组实现降序后是:");
            Array.Reverse(myintArray);
            foreach(int outint in myintArray)
            {
                Console.Write(outint + "  ");
            }
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}

数组排序

Array类提供了两种方法Sort和Reverse用于数组排序。

【程序分析】本例演示了如何对数组进行排序。在代码中,定义了一个int类型的一维数组myintArray并初始化,然后分别使用Sort和Reverse对其进行升序和降序的排列。

原数组是:
11  5  89  17  20  63  12  18  9  29  37  14
数组实现升序后是:
5  9  11  12  14  17  18  20  29  37  63  89
数组实现降序后是:
89  63  37  29  20  18  17  14  12  11  9  5

数组合并与拆分

数组的拆分与合并并不是针对一个数组进行操作的,而是将两个数组合并到第三个数组中去。在C#中数组的拆分与合并是通过Array类提供的Copy方法实现的。
编写程序,定义两个数组,并对这两个数组进行拆分与合并的操作。

using System;
namespace Project14
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] arr1 = { 9,1,2,3,4,5,6,7,8};
            int[] arr2 = { 11,12,13,14,15,16,17,18,19};
            Console.WriteLine("原arr1数组为:");
            foreach (int outarr in arr1)
            {
                Console.Write(outarr+"  ");
            }
            Console.WriteLine("\n原arr2数组为:");
            foreach (int outarr in arr2)
            {
                Console.Write(outarr+"  ");
            }
            Console.WriteLine("\n合并arr1与arr2");
            int[] NumArr1 = new int[18];
            //表示将arr1中的数组元素从索引值0开始,取9个元素,放入NumArr1数组中
            //注意:在NumArr1中从索引值0开始存放
            Array.Copy(arr1, NumArr1, 9);
            //数组arr2索引值从0开始取9个长度,放入到NumArr1中,并从索引值9开始存放
            Array.Copy(arr2, 0, NumArr1, 9, 9);           
            foreach (int outarr in NumArr1)
            {
                Console.Write(outarr + "  ");
            }
            Console.WriteLine("\n拆分数组");
            int[] NumArr2 = new int[5];
            //数组NumArr1索引值从11开始取5个长度,放入到NumArr2中,并从索引值0开始存放
            Array.Copy(NumArr1, 11, NumArr2, 0,5);
            Console.WriteLine("拆分后的结果");
            foreach (int outarr in NumArr2)
            {
                Console.Write(outarr + "  ");
            }
            Console.WriteLine();
            Console.ReadKey();
        }
    }
}

【程序分析】本例演示了如何对数组进行拆分与合并。在代码中,首先定义两个数组arr1和arr2,并为其进行初始化赋值;接着使用foreach循环遍历出两个数组;然后使用Copy方法,进行合并操作,首先将arr1中的数组元素从索引值0开始,取9个元素,放入NumArr1数组中,再通过Copy方法将数组arr2索引值从0开始取9个长度,放入到NumArr1中,并从索引值9开始存放;进行拆分操作时也使用Copy方法,将数组NumArr1索引值从11开始取5个长度,放入到NumArr2中,并从索引值0开始存放。

原arr1数组为:
9  1  2  3  4  5  6  7  8
原arr2数组为:
11  12  13  14  15  16  17  18  19
合并arr1与arr2
9  1  2  3  4  5  6  7  8  11  12  13  14  15  16  17  18  19
拆分数组
拆分后的结果
13  14  15  16  17

你可能感兴趣的:(VS-C#,c#)