数组
数组
定义
重要细节
数组的类型
数组是对象
一维数组和矩形数组
实例化一维数组或矩形数组
访问数组元素
初始化数组
显式初始化一维数组
显式初始化矩形数组
快捷语法
隐式类型数组
综合内容
交错数组
声明交错数组
快捷实例化
实例化交错数组
比较矩形数组和交错数组
foreach语句
迭代变量是只读的
foreach语句和多维数组
数组协变
数组继承的有用成员
Clone方法
比较数组类型

数组

数组


数组实际上是由一个变量名称表示的一组同类型的数据元素。每个元素通过变量名称和一个或多个方括号中的索引来访问:

数组名  索引↓     ↓
MyArray[4]
定义

让我们从C#中与数组有关的重要定义开始

  • 元素 数组的独立数据项称为元素。数组的所有元素必须是同类型的,或继承自相同的类型
  • 秩/维度 数组可以有任何为正数的维度数。数组的维度数称作秩(rank)
  • 维度长度 数组的每个维度都有一个长度,就是这个方向的位置个数
  • 数组长度 数组的所有维度中的元素的总和称为数组的长度
重要细节

关于C#数组的一些要点:

  • 数组一旦创建,大小就固定了。C#不支持动态数组
  • 数组索引号从0开始。如果维度长度是n,索引号范围就是0到n-1

数组的类型


C#提供两种类型的数组

  • 一维数组可以认为是单行元素或元素向量
  • 多维数组是由主向量中的位置组成的。每个位置本身又是一个数组,称为子数组(subarray)。子数组向量中的位置本身又是一个子数组

另外,有两种类型的多维度数组:矩形数组(rectangular array)和交错数组(jagged array),它们有如下特性:

  • 矩形数组
    • 某个维度的所有子数组具有相同长度的多维数组
    • 不管有多少个维度,总是使用一组方括号 int x=myArray2[4,6,1]
  • 交错数组
    • 每个子数组都是独立数组的多维度数组
    • 可以有不同长度的子数组
    • 为数组的每个维度使用一对方括号 jagArray1[2][7][4]

数组是对象


数组实例是从System.Array继承的对象。由于数组从BCL(Base Class Library)基类继承,它们也继承了很多有用的方法。

  • Rank 返回数组维度数
  • Length 返回数组长度(数组中所有元素的个数)

数组是引用类型,与所有引用类型一样,有数据的引用以及数据对象本身。引用在栈或堆上,而数组对象本身总在堆上。


尽管数组总是引用类型,但是数组元素可以是值类型也可以是引用类型。

  • 如果存储的元素都是值类型,数组被称作值类型数组
  • 如果存储的元素都是引用类型,数组被称作引用类型数组

一维数组和矩形数组


一维数组和矩形数组的语法非常相似,因此放在一起阐述。然后再单独介绍交错数组。

声明一维数组或矩形数组
声明一维数组或矩形数组,在类型和变量名称间使用一对方括号。
矩形数组声明示例:

  • 可以使用任意多的秩说明符
  • 不能在数组类型区域中放数组维度长度。秩是数组类型的一部分,而纬度长度不是类型的一部分
  • 数组声明后,维度数就固定了。然而,纬度长度直到数组实例化时才确定
 秩说明符↓
int[,,] firstArray;     //三维整型数组
int[,]  arr1;           //二维整型数组
long[,] arr3;           //三维long数组
long[3,2,6] SecondArray;//编译错误
       ↑
声明时不允许设置维度长度

和C/C++不同,方括号在基类型后,而不是在变量名称后。

实例化一维数组或矩形数组


要实例化数组,我们可以使用数组创建表达式。数组创建表达式由new运算符构成,后面是基类名称和一对方括号。方括号中以逗号分隔每个维度的长度。

例:

int[] arr2=new int[4];//包含4个int的一维数组
MyClass[] maArr=new MyClass[4];//包含4个MyClass引用的一维数组
int[,,] arr3=new int[3,6,2];//三维数组,数组长度是3*6*2=36

与对象创建表达式不一样,数组创建表达式不包含圆括号-即使是对于引用类型数组。

访问数组元素


在数组中使用整型值作为索引来访问数组元素。

  • 每个维度的索引从0开始
  • 方括号内的索引在数组名称之后
int[] intArr1=new int[15];
intArr1[2]=10;
int var1=intArr1[2];
int[,] intArr2=new int[5,10];
intArr2[2,3]=7;
int var2=intArr2[2,3];
int[] myIntArray;
myIntArray=new int[4];
for(int i=0;i<4;i++)
{myIntArray[i]-i*10;
}
for(int i=0;i<4;i++)
{Console.WriteLine("Value of element {0} = {1}",i,myIntArray[i]);
}

初始化数组


数组被创建后,每个元素被自动初始化为类型的默认值。对于预定义类型,整型默认值是0,浮点型默认值是0.0,布尔型默认值是false,而引用类型默认值则是null。
例:一维数组的自动初始化

int[] intArr=new int[4];

显式初始化一维数组
  • 初始值必须以逗号分隔,并封闭在一组大括号内
  • 不必输入数组长度,因为编译器可以通过初始化值的个数来推断长度
  • 注意,在数组创建表达式和初始化列表中间没有分隔符。即,没有等号或其他连接运算符
int[] intArr=new int[]{10,20,30,40};

显式初始化矩形数组

要显式初始化矩形数组,需遵守以下规则:

  • 每个初始值向量必须封闭在大括号内
  • 每个维度也必须嵌套并封闭在大括号内
  • 除了初始值,每个维度的初始化列表和组成部分也必须使用逗号分隔
int[,] intArray2=new int[,]{{10,1},{2,10},{11,9}};

快捷语法

在一条语句中使用声明、数组创建和初始化时,可以省略语法的数组创建表达式部分。快捷语法如下:

int[] arr1=new int[3]{10,20,30};
int[] arr1=          {10,20,30};
int[,] arr=new int[2,3]{{0,1,2},{10,11,12}};
int[,] arr=            {{0,1,2},{10,11,12}};
隐式类型数组

上面声明的数组都是显式指定数组类型。然而,和其他局部变量一样,数组可以是隐式类型的。

  • 当初始化数组时,我们可以让编译器根据初始化语句的类型来推断数组类型。只要所有初始化语句能隐式转换为单个类型,就可以这么做
  • 和隐式类型的局部变量一样,使用var关键字

虽然用var替代了显式数组类型,但是仍然需要在初始化中提供秩说明符。

int[] intArr1=new int[]{10,20,30,40};
var   intArr2=new    []{10,20,30,40};
int[,] intArr3=new int[,]{{10,1},{2,10},{11,9}};
var    intArr4=new    [,]{{10,1},{2,10},{11,9}};
string[] sArr1=new string[]{"life","liberty","pursuit of happiness"};
var      sArr2=new       []{"life","liberty","pursuit of happiness"};
综合内容

例:综合示例

var arr=new int[,]{{0,1,2},{10,11,12}};
for(int i=0;i<2;i++)
{for(int j=0;j<3;j++){Console.WriteLine("Element [{0},{1}] is {2}",i,j,arr[i,j]);}
}

交错数组


交错数组是数组的数组。与矩形数组不同,交错数组的子数组的元素个数可以不同。

例:二维交错数组

  • 第一个维度长度是3
  • 声明可以读作“jagArr是3个int数组的数组”
  • 图中有4个数组对象-其中一个针对顶层数组,另外3个针对子数组
int[][] jagArr=new int[3][];

声明交错数组

交错数组的声明语法要求每个维度都有一对独立的方括号。数组变量声明中的方括号数决定了数组的秩。
和矩形数组一样,维度长度不能包括在数组类型的声明部分。

int[][] SomeArr;//秩等于2
int [][][] OhterArr;//秩等于3
快捷实例化

我们可以将数组创建表达式创建的顶层数组和交错数组的声明相结合。

int[][] jagArr=new int[3][];//3个子数组

不能在声明语句中初始化顶层数组之外的数组。

int[][] jagArr=new int[3][4];//不允许,编译错误
实例化交错数组

和其他类型数组不一样,交错数组的完全初始化不能在一个步骤中完成。由于交错数组是独立数组的数组-每个数组必须独立创建。

  1. 首先,实例化顶层数组
  2. 其次,分别实例化每个子数组,把新建数组的引用赋给它们所属数组的合适元素

例:实例化交错数组

int[][] Arr=new int[3][];
Arr[0]=new int[]{10,20,30};
Arr[1]=new int[]{40,50,60,70};
Arr[3]=new int[]{80,90,100,110,120};

比较矩形数组和交错数组


矩形数组和交错数组的结构区别非常大。
例如,下图演示了3X3的矩形数组以及由3个长度为3的一维数组构成的交错数组的结构。

  • 两个数组都保存9个整数,但是它们结构很不相同
  • 矩形数组只有1个数组对象,而交错数组有4个数组对象


在CIL(Common Intermediate Laguage,公共中间语言)中,一维数组有特定的指令用于性能优化。矩形数组没有这些指令,并且不在相同级别进行优化。因此,有时使用一维数组(可以被优化)的交错数组比矩形数组(不能被优化)更有效率。
另一方面,矩形数组的编程复杂度要小得多,因为它会被作为一个单元而不是数组的数组。

foreach语句


foreach语句允许我们连续访问数组中的每个元素。
有关foreach语句的重点如下:

  • 迭代变量是临时的,并且和数组中元素的类型相同。foreach语句使用迭代变量来相继表示数组中的每个元素
  • foreach语句的语法如下
    • Type是数组中元素的类型。我们可以显式提供它的类型,或者使用var
    • Identifier是迭代变量名
    • ArrayName是数组名
    • Statement是要为数组中每个元素执行一次的单条语句或语句块
foreach(Type Identifier in ArrayName)//显式
{Statement
}
foreach(var Identifier in ArrayName)//隐式
{Statement
}

foreach如下方式工作:

  • 从数组第一个元素开始并把它赋值给迭代变量
  • 执行语句主体。在主体中,我们可以把迭代变量作为数组元素的只读别名
  • 主体执行后,foreach语句选择数组中的下一个元素并重复处理

例:foreach示例

int[] arr1={10,11,12,13};
foreach(int item in arr1)
{Console.WriteLine("Item Value: {0}",item);
}

迭代变量是只读的

迭代变量是只读的。但是,对于值类型数组和引用类型数组效果不一样。
对于值类型数组,这意味着在用迭代变量时,我们不能改变它们。

例:尝试修改迭代变量报错

int[] arr1={10,11,12};
foreach(int item in arr1)
{item++;
}

对于引用变量,迭代变量保存的是数据的引用,而不是数据本身。所以,我们虽然不能改变引用,但是我们可以改变数据。

例:引用变量修改迭代变量

class MyClass
{public int MyField=0;
}
class Program
{static void Main(){MyClass[] mcArray=new MyClass[4];for(int i=0;i<4;i++){mcArray[i]=new MyClass();mcArray[i].MyField=i;}foreach(var item in mcArray){item.MyField+=10;}foreach(var item in mcArray){Console.WriteLine("{0}",item.MyField);}}
}

foreach语句和多维数组

多维数组里,元素处理顺序是从最右边的索引号依次递增。

例:矩形数组示例

class Program
{static void Main(){int total=0;int[,] arr1={{10,11},{12,13}};foreach(var element in arr1){total+=element;Console.WriteLine("Element:{0},Current Total:{1}",element,total);}}
}


例:交错数组示例

class Program
{static void Main(){int total=0;int[][] arr1=new int[2][];arr1[0]=new int[]{10,11};arr1[1]=new int[]{12,13,14};foreach(int[] array in arr1){Console.WriteLine("Starting new array");foreach(int item in array){total+=element;Console.WriteLine("Item:{0},Current Total:{1}",item,total);}}}
}

数组协变


某些情况下,即使某对象不是数组的基类型,我们也可以把它赋给数组元素。这种属性叫做数组协变(array covariance)。在下面情况下使用数组协变。

  • 数组是引用类型数组
  • 在赋值的对象类型和数组基类之间有隐式转换或显式转换

由于派生类和基类之间总有隐式转换,因此总是可以把派生类对象赋值给基类声明的数组。

例:派生类、基类 数组协变

class A{...}
class B:A{...}
class Program
{static void Main(){A[] AArray1=new A[3];A[] AArray2=new A[3];AArray1[0]=new A();AArray1[1]=new A();AArray1[2]=new A();AArray2[0]=new B();AArray2[1]=new B();AArray2[2]=new B();}
}

值类型数组没有协变

数组继承的有用成员


C#数组从System.Array类继承。它们从基类继承了很多有用的属性和方法。

public static void PrintArray(int[] a)
{foreach(var x in a){Console.WriteLine("{0}",x);}Console.WriteLine("");
}
static void Main()
{int[] arr=new int[]{15,20,5,25,10};PrintArray(arr);Array.Sort(arr);PrintArray(arr);Array.Reverse(arr);PrintArray(arr);Console.WriteLine();Console.WriteLine("Rank = {0},Length = {1}",arr.Rank,arr.Length);Console.WriteLine("GetLength(0)      = {0}",arr.GetLength(0));Console.WriteLine("GetType()         = {0}",arr.GetType());
}

Clone方法

Clone方法为数组进行浅复制。即,它只创建了数组本身的克隆。如果是引用类型数组,它不会复制元素引用的对象。对于值类型数组和引用类型数组,效果不同。

  • 克隆值类型数组会产生两个独立数组
  • 克隆引用类型数组会产生指向相同对象的两个数组

Clone方法返回object类型的引用,它必须被强制转换成数组类型。

int[] intArr1={1,2,3};
int[] intArr2=(int[])intArr1.Clone();

例:Clone值类型数组示例

class Program
{static void Main(){int[] intArr1={1,2,3};int[] intArr2=(int[])intArr1.Clone();intArr2[0]=100;intArr2[1]=200;intArr2[2]=300;}
}


例:Clone引用类型数组示例

class A
{public int Value=5;
}
class Program
{static void Main(){A[] AArray1=new A[3]{new A(),new A(),new A()};A[] AArray2=(A[])AArray1.Clone();AArray2[0].Value=100;AArray2[1].Value=200;AArray2[2].Value=300;}
}

比较数组类型


下表总结了3中类型数组的重要相似点和不同点。


转载于:https://www.cnblogs.com/moonache/p/6255327.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/255646.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/255646.shtml
英文地址,请注明出处:http://en.pswp.cn/news/255646.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据库学习】——windows、MySQL构建新闻管理系统(控制台版)

学习记录&#xff1a;【Python项目实战】PythonMySQL开发新闻管理系统全集_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Qb4y1b75q?p2&spm_id_frompageDriver 目录 一、项目介绍 1、项目结构 2、系统部分功能提前展示 3、项目流程图 4、项目设计的数据库以及…

matlab张量工具初步

最近从桑迪亚实验室下载了张量工具包。但是不太会用。 很多网上的方法&#xff0c; addpath(pwd) cd met; addpath(pwd) savepath Mones(4,3,2); Xtensor(M); Xtensor(rand(5,1)) Ytensor(rand(4,3,1)) Xtenrand([4 3 2]) X.size %*************************** Rsptenrand([5 4…

微信红包API接口(PHP)

发布时间&#xff1a;2015年2月25日 / 分类&#xff1a;WEB开发,PHP / 74,825 / 241 ℃ 根据微信高级红包接口&#xff0c;开发PHP版本的API接口&#xff0c;现在进行主要代码分析。 红包接口调用请求代码&#xff0c;所有请求参数为必填参数与文档对应&#xff1a; 1234567891…

2016年个人技术总结(前端)

自我总结 参与项目 备注:[☆-表示比较吊的项目,-从头开始做,^-中间加入项目] 神马生活(微信公众号商城)[^] 神马学院[] <!------跳槽线--------> 大数据套件[☆][^] fable数据营销平台(加入新功能&#xff0c;交互)[^] fit问卷系统[] fit投放系统[] fit画像[^] 理财通点击…

浅谈OpenCV[轉]

OpenCV是一个由Interl公司支持的开源机器视觉库&#xff0c;关于它的介绍&#xff0c;网上随便一搜就车载斗量。这里我不谈OpenCV的主要内容&#xff0c;而是将这段时间来对它的使用心得作个简单介绍&#xff0c;以启发打算用这个库的朋友的思路&#xff0c;与大家一起来分享。…

【pyqt5学习】——tablewidget控件学习

目录 1、Table Widget 1.QTableWidget不能在mainwindow中随主窗口的大小变化&#xff1f; 2.将表格变为禁止编辑&#xff1a; 3.设置表格为整行选择 4.单个选中和多个选中的设置&#xff1a; 5.表格表头的显示与隐藏 6.对表头文字的字体、颜色进行设置 7.在单元格里加入…

吴忠军 - 如何理解马云所说的月入两三万,三四万的人最幸福?

这句话源于一段两分钟的视频&#xff0c;马云的一次阿里内部会议演讲。 马云坦承&#xff0c;自己从第一天起就没想过当首富&#xff0c;还为此稀释公司持股&#xff0c;“没想到把自己的股份降到8%&#xff0c;还是有那么多&#xff0c;这是我没有想到的。” 在马云看来&#…

iOS小知识点(非UI部分)

1。 _cmd 表示当前方法的SEL指针&#xff0c; - (void)putString{} 对于这个函数_cmd 等效于selector(putString)转载于:https://www.cnblogs.com/dongfangchun/p/5341599.html

jQuery 操作 CSS

jQuery 拥有若干进行 CSS 操作的方法。我们将学习下面这些&#xff1a; addClass() - 向被选元素添加一个或多个类removeClass() - 从被选元素删除一个或多个类toggleClass() - 对被选元素进行添加/删除类的切换操作css() - 设置或返回样式属性转载于:https://www.cnblogs.com/…

彩色CCD相机工作原理

原理 黑白&#xff08;单色&#xff09;相机 CCD原理并不复杂。我们可以把它想象成一个顶部被打开的记忆芯片。因此光束可以射到记忆单元中。根据"光电效应”&#xff0c;这些光束在记忆单元中产生负电荷&#xff08;下图中右上部分&#xff09;。 曝光后&…

Linux 系统常用命令汇总(二) vi 文本编辑

文本编辑vi命令作用文件名编辑文本文件&#xff0c;若文件不存在同时创建该文件Ctrlf向后翻一页Ctrlb向前翻一页Ctrld向后翻半页Ctrlu向前翻半页光标移动到下一行-光标移动到上一行数字空格光标向右移动n个字符0移动到本行首个字符处$ 移动到本行最后一个字符处H光标移动到屏幕…

图像处理与计算机视觉:基础,经典以及最近发展(2)图像处理与计算机视觉相关的书籍

1. 数学 我们所说的图像处理实际上就是数字图像处理&#xff0c;是把真实世界中的连续三维随机信号投影到传感器的二维平面上&#xff0c;采样并量化后得到二维矩阵。数字图像处理就是二维矩阵的处理&#xff0c;而从二维图像中恢复出三维场景就是计算机视觉的主要任务之一。这…

【HTML学习】——HTML常见标签属性和方法介绍

目录 1、HTML分块--------< div> 2、HTML段落--------< p> 3、HTML标题--------< h1>…< h6> 4、HTML链接--------< a> 1)< a href“http://www.baidu.com”>百度< /a>&#xff08;点击百度&#xff0c;直接跳转到网页&#xf…

开发者应警惕的七种糟糕职业规划错误

那些心灵鸡汤式的说辞总爱美化失败&#xff1a;失败是成功之母啦、失败使人成长啦、别畏惧失败等等。但事实上&#xff0c;这种思路在软件开发领域也许并不适用——至少不完全适用。每位开发者在职业生涯中都不可避免会遭遇失败&#xff0c;但为什么不从他人的经验中汲取教训来…

Splay模板

打LCT的时候发现Splay很不熟, 因此这里贴一下模板 洛谷P3369 https://www.luogu.org/problem/show?pid3369#sub /* 提一些要注意的点: 1. 注意判断边界, 不要访问到空节点 2. 每一次操作或访问完以后, 记得要splay到root 3. insert操作只要update当前节点和父亲节点即可, 因为…

图像处理与计算机视觉 基础、经典以及最近发展

申明&#xff1a;本文非笔者原创&#xff0c;原文转载自&#xff1a;http://blog.csdn.net/liuyue2046/article/details/12658441 ***************************************************************************************************************************************…

【HTML学习】——一个网页HTML编程的构成

目录 1、html网页构成介绍 2、HTML标签介绍 全部的html标签&#xff1a; HTML: HyperText Markup Language | MDNhttps://developer.mozilla.org/en-US/docs/Web/HTML 一个网页文件一般由.html结尾的文件组成&#xff0c;主要由不同的标签对和内容组成&#xff0c;常见的html…

hbase里插入big int数据用Phoenix查看的报错问题

Phoenix建表create table "test_big_int"("ROW" varchar primary key,"ci"."column1" bigint) 在hbase里put数据hbase 里面进行put: put test_big_int,001,ci:column1,1 在Phoenix里进行查看&#xff08;问题出现&#xff09;第二个尝…

机器学习:利用卷积神经网络实现图像风格迁移 (一)

相信很多人都对之前大名鼎鼎的 Prisma 早有耳闻&#xff0c;Prisma 能够将一张普通的图像转换成各种艺术风格的图像&#xff0c;今天&#xff0c;我们将要介绍一下Prisma 这款软件背后的算法原理。就是发表于 2016 CVPR 一篇文章&#xff0c; “ Image Style Transfer Using Co…

jquery中attr和prop的区别

在高版本的jquery引入prop方法后&#xff0c;什么时候该用prop&#xff1f;什么时候用attr&#xff1f;它们两个之间有什么区别&#xff1f;这些问题就出现了。 关于它们两个的区别&#xff0c;网上的答案很多。这里谈谈我的心得&#xff0c;我的心得很简单&#xff1a; •对于…