第五章:数组/Array/Tuple/yield

数组

如果需要使用同一类型的多个对象,就可以考虑使用集合和数组.如果需要使用不同类型的多个对象,可以考虑使用Tuple(元组)

数组的声明

在声明数组时,应先定义数组元素中的类型,其后是一对空方括号和变量名

int[] myAyyay;

 数组初始化

声明了数组之后,就必须为数组分配内存,以保存数组的元素,数组是引用类型,所以必须给它分配堆上的类型,为此,需要使用new运算符,指定数组元素的数据类型和数量来初始化数组

myArray=new int[10];

在指定了数组大小后,如果不复制数组中的所有元素,就不能重新设置数组大小,如果事先不知道数组应包含多少元素,就应该使用集合

可以在数组声明时,同时初始化数组

int[] myArray= new int[10];

使用数组初始化器在声明数组变量时为数组赋值

int[] myArray= new int[4]{1,2,4,5};

此时还可不指定数组大小

int[] myArray= new int[]{1,2,4,5};

更简化的方式

int[] myArray={1,2,5,4};

访问数组元素

在声明和初始化数组后,就可以通过索引器来访问其中的元素,数组只支持有整型参数的索引器,并索引总是从0开始;如果使用超出数组长度的索引器来访问数组元素,就会造成数组越界

int value= myArray[2];

定义自定义类型数组;如果数组中的元素是引用类型,就必须为每个数组元素分配内存

class Program
    {
        static void Main(string[] args)
        {
            int[] intArray = { 1, 2, 5, 4 };
            string[] stringArray = { "我", "你", "他" };

            Person[] persons =  {
                new Person { Name = "w", Age = 1 },
                new Person { Name = "l", Age = 2 }
            };
            Console.WriteLine(intArray[2]);
            Console.WriteLine(stringArray[2]);
            Console.WriteLine(persons[0].Age);
            Console.ReadKey();
        }
    }
    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public override string ToString()
        {
            return string.Format("{0},{1}", Name, Age);
        }    }

多维数组

一维数组使用一个整数来索引.多维数组使用两个或多个整数来索引

            //事先不知道元素的值
            int[,] array = new int[2, 2];
            array[0, 0] = 1;
            array[0, 1] = 1;
            array[0, 2] = 1;
            array[1, 0] = 1;
            array[1, 1] = 1;

            //事先知道元素的值
            int[,] array1 = {
                { 1,2,},
                { 4,5,},
            };
            //使用两个","声明三维数组
            int[,,] array3 = {
                { { 1,2},{ 3,4} },
                { { 5,6},{ 7,8} },
            };

注意:声明数组后,就不能修改阶数了

锯齿数组

在锯齿数组中,每一行都可以有不同的大小

int[][] jagged= new int[3][];
jagged[0]= new int[2]{1,2};
jagged[1]= new int[3]{7,8,9};

Array

用方括号声明数组是C#使用Array累的表示法,Array类是一个抽象类,所以不能使用构造函数来创建数组,但是除了可以使用C#语法创建数组外,还可以使用静态方法CreateInstance()创建数组;如果实现不知道元素类型,该静态方法非常有用

            Array array = Array.CreateInstance(typeof(int), 3);
            for (int i = 0; i < array.Length; i++)
            {
                array.SetValue(1, i);
            }
            for (int i = 0; i < array.Length; i++)
            {
                Console.WriteLine(array.GetValue(i));
            }
            foreach (var item in array)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();

复制数组

因为数组是应用类型,所以将一个数组变量赋予另一个数组变量,就会得到两个引用同以数组的变量,而复制数组,会使数组实现ICloneeable接口,这个接口定义的Clone方法会创建数据的浅表副本

   class Program
    {
        static void Main(string[] args)
        {
            //***********值类型*****************
            int[] array = { 1, 2, 3 };

            int[] array2 = (int[])array.Clone();
            array2[1] = 6;

            foreach (var item in array)
            {
                Console.WriteLine("array:{0}", item);
            }
            foreach (var item in array2)
            {
                Console.WriteLine("array2:{0}", item);
            }
            //***********引用类型*****************
            Person[] persons = {
                new Person{ Name="w"},
                new Person{ Name="l"}
            };
            Person[] persons2 = (Person[])persons.Clone();
            persons2[0].Name = "哈哈";
            foreach (var item in persons)
            {
                Console.WriteLine("persons:{0}", item.Name);
            }
            foreach (var item in persons2)
            {
                Console.WriteLine("persons2:{0}", item.Name);
            }
            Console.ReadKey();
        }
    }

    class Person
    {
        public string Name { get; set; }
    }

因为array是值类型,改变array2元素的值,并不会影响array自身;persons是引用类型所以,对persons2的改变会影响persons的值

除了使用Clone方法外,也可以使用Array.Copy()方法来创建浅表副本,区别在于:Clone()方法会创建一个新数组,而Copy()方法必须传递阶数相同且有足够元素的已有数组

ArraySegment<T>

结构ArraySegment<T>表示数组中的一段.如果需要使用不同的方法处理数组的不同部分,如果按照正常方式处理,可以通过将数组部分复制到各个方法中,但是这么做会在不同的方法中都创建新的数组,更有效的方法是使用同一个数组.在不同的方法中使用数组的不同部分;数组段不复制原数组的元素,但原数组可以通过ArraySegment<T>访问,如果数组中元素改变了,变化会映射到原数组中

原文地址:https://www.cnblogs.com/GnailGnepGnaw/p/10618666.html

时间: 2024-10-12 10:59:57

第五章:数组/Array/Tuple/yield的相关文章

Java基础知识二次学习--第五章 数组

第五章 数组 时间:2017年4月26日15:11:30~2017年4月26日15:15:54 章节:05章_01节  视频长度:09:30 内容:一维数组的内存分析 心得: Java中数组是引用类型 栈里面存的数组的引用 实际对象在堆内存里面 (C与C++是分配在栈里的) 内存图: 元素为引用数据类型的数组 引用类型的数组如上图 时间:2017年4月26日15:16:22~2017年4月26日15:19:00 章节:05章_02节  视频长度:05:25 内容:数组元素的创建与使用 心得: 首

数据结构期末复习第五章数组和广义表

数据结构期末复习第五章 数组和广义表 二维数组A[m][n]按行优先 寻址计算方法,每个数组元素占据d 个地址单元.     设数组的基址为LOC(a11) :LOC(aij)=LOC(a11)+((i-1)*n+j-1)*d     设数组的基址为LOC(a00) :LOC(aij)=LOC(a00)+( i*n+j )*d    二维数组A[m][n]按列优先 寻址计算方法,每个数组元素占据d 个地址单元.     设数组的基址为LOC(a11) :LOC(aij)=LOC(a11)+((j

第五章 数组(1):数组声明和初始化

搞了一年多的android ,现在又回到c语言了,最基础的都不知道了,今天声明数据居然还用变量做大小,罪过啊 数组(array)是若干同类变量的聚合,允许通过统一的名字引用其中的变量.其特定元素通过下标(index)访问.C语言的数组由连续的内存区构成,最低地址对应首元素,最高地址对应末元素. 保存数组所需要的内存量直接与基类型和数组大小有关.对一维数组而言,以字节为单位的总内存量可以这样来确定: 总字节数 = sizeof (基类型)×数组长度 例如,一维数组x int x[100]; 它所占

JAVA-初步认识-第五章-数组-常见操作-选择排序

一. 排序 元素有很多的情况下,我们都希望元素按照指定的方式有一个顺序,比如说由小到大.排序的方式有很多种,我们讲解其中一种. 例子: 对上面的数组中的元素排个序,从小到大.这个想不出来,之前谈论的是两个数比较,得到大的数. 听了视频的一点讲解,突然有了思路,角标0和角标1进行比较后,将元素的大小做了调换,再继续将角标0和剩余角标的元素进行比较,最终保证角标0中的元素是所有角标中最小的.接着重复将角标1和后面角标中的元素进行比较,再得出一个最小的值,如此往复.这里排序的时候,有一点是要注意的,角

第五章 数组

5.1 一维数组 void main() { int A[5],i,min,min_index; for(i=0;i<5;i++) { scanf("%d",&A[i]); } min = A[0],min_index = 0; for(i=1;i<5;i++) { if(min > A[i]) { min = A[i]; min_index = i; } } printf("No:%d:%d\n",min_index,min); syst

JAVA-初步认识-第五章-数组-常见操作-最值

一. 最值 在视频没有讲解怎么做之前,我先提供一个思路.得出最值肯定是一个一个地比较出来的,这种多次的比较操作,那肯定用到循环结构.每一次操作都要得出两个数中的最大值,也就是说还有判断的if语句.相当于说在循环结构语句中嵌套if判断语句.和视频的讲解对比,我唯一欠缺的是没有说明每次比较的数值是个变量. 同视频讲解对比,自己的思路中没有提到功能化函数.我推测的原因是,需求是要获取最大值,而非我想像的输出最大值,输入数组直接得到最大值,这是一种功能. 注解:这上面求解最值,有两种思路.一种是拿元素进

JAVA-初步认识-第五章-数组-第二种定义格式

一. 数组书写的第二种格式 事物为什么会有不同的种类的出现?一定要用发展的眼光看问题. 数组格式1的问题在于,内存中开辟数组空间时,没有定义内部数据的大小,都是默认值.格式2(常规地初始化数组的方式)为了克服这一点,在定义时,直接将数据大小输入数组. 创建数组的同时,指定好了数组中每一个角标位置上的元素. 上面的截图中还显示了格式2的一个便捷写法(静态初始化方式),但是它和格式2稍微有点小区别,后面会谈论到. 二 格式1:需要一个容器,但不明确容器中的具体数据. 格式2:需要一个容器,存储已知的

JAVA-初步认识-第五章-数组-常见操作-遍历

一. 数组操作 定义好数组后,要存储在数组中的数据拿出来操作.怎么取? 对于数组操作最重要的操作有两种,一个是存,另一个是取.同时,基于这两个操作又衍生出常见的功能性操作. 存取的核心思想:对角标的操作. 二. 之前要求的都是输出数组中的单个数据,如果要求输出数据中的全部数据,仔细观看下面的操作.为了提高复用性,可以采用循环结构来书写语句,while和for都可以,但是for定义的局部代码块可以释放变量.数组操作完,就结束了,称为了垃圾,采用for更好. 如果数组内的元素数目特别多,我们要想全部

JAVA-初步认识-第五章-数组-常见操作-冒泡排序

一. 冒泡排序 这里介绍了另一种排序的方法,冒泡排序法.选择排序法比较接近人们正常的思维,一个数据和剩下的说有数据比较. 冒泡排序法是临近的数据间进行比较,大的数据就调到右侧,角标1-2的数据对比,角标2-3的数据对比...... 无论是选择排序还是冒泡排序都是先求最值. 冒泡排序法,是一轮一轮地进行左右两侧的数据进行对比.第一轮将所有数据中最大的数据移动到了最右侧,这种操作的核心在于:一直保证大的数据在右侧,那么经过不断地对调,最大的数据肯定在最后一位中.第一轮将最大的数据移动到了最右边,接下