c#笔记-数组

news/2024/12/2 10:37:18/

数组

声明数组

数组是一种可以声明多个同类型变量的数据结构,能替你声明多个变量。
并且其中的值可以通过索引动态访问,可以搭配循环批量处理这些值。

数组类型的写法是,在目标类型后加上一对中括号。
数组值没有字面量,需要构造出来。

int[] arr1 = new int[10];//构造一个int数组,它里面有10个int
var arr2 = new int[10];//var能识别出数组类型,不需要在var后加中括号

访问内容

通过int访问

数组的元素通过变量后加一对中括号,并指示索引来访问他的第n个元素。
获取到的元素跟普通的int类型值是一样的。
可以为int变量赋值,可以接收int值,也可以进行数学运算。

int[] arr3 = new int[4];
arr3[0] = 12;
arr3[1] = 16;
arr3[2] = 64;
arr3[3] = arr3[0] + arr3[1];
Console.WriteLine(arr3[3] - arr3[2]);

他的索引不仅能使用字面量,也可以使用变量。

int[] arr5 = new int[10];
for (int i = 0; i < arr5.Length; i++)
{arr5[i] = i * i;
}
for (int i = 0; i < arr5.Length; i++)
{Console.WriteLine(arr5[i]);
}

通过Index访问

通过Index可以从后往前访问数组的元素。他的写法是在数字前写一个^

int[] arr6 = new int[10];
arr6[^1] = 18;
arr6[^2] = 16;
arr6[^3] = 14;
arr6[^9] = 2;
arr6[^10] = 1;
Console.WriteLine(arr6[0]);
Console.WriteLine(arr6[1]);
Console.WriteLine(arr6[7]);
Console.WriteLine(arr6[8]);
Console.WriteLine(arr6[9]);
  • var可以知道^1的类型是Index
  • ^1不是运算符,而是语法糖。它要求编译器构造一个Index类型的值。
  • ^1不是字面量,而是指令。所以无法声明Index的常量

也可以配合变量来构造一个Index

int[] arr7 = new int[2];
arr7[0] = 18;
Console.WriteLine(arr7[^arr7.Length]);

数组长度

索引越界

对数组元素的访问,只能访问有效索引。
有效索引从0开始数,总数量等于数组长度。所以最大的有效索引为数组长度-1

数组长度可以通过访问数组的.Length属性获取。

而对于Index类型来说,^1表示倒数第一个元素。相当于arr[arr.Length - 1]
Index的倒数最大有效值为数组的Length

无论使用int还是Index,如果访问了非法的索引,那么或报错索引越界
c#是类型安全语言。数组控制之外的元素依旧按照相同的逻辑访问,可能会访问到其他程序的内存。

数组长度可以为0,此时任何索引都是非法的。

长度固定

之前的类型都是简单类型。他们没有内容。
任何对值的修改都是通过修改变量本身来完成的。

而数组的元素,是数组的内容。可以在不修改他的变量的情况下,来改变它的值。
也因为数组的元素是数组的内容,所以你在使用他们前,不需要像变量一样先赋值初始值。

数组是一个基本的数据结构。它高效,但一旦完成声明,就不能再改变他的长度。
这是说你不能在不修改变量的情况下修改长度。你仍然可以新建一个数组,重新对数组变量赋值。

指针

引用类型

如果你直接用一个数组变量来给另一个数组变量赋值,你会发现他们会窜号。

int[] arr8 = new int[1];
int[] arr9 = arr8;
Console.WriteLine(arr8[0]);//0
Console.WriteLine(arr9[0]);//0
arr8[0] = 12;
Console.WriteLine(arr8[0]);//12
Console.WriteLine(arr9[0]);//12

这是因为数组是引用类型。引用类型是一些无法预测大小,内容过大,和一些躺枪的数据。
这些的数据(数组元素)是存放在内存上的。

·内存储存了程序的运行到哪的指令信息,和一些临时信息。
在你构建完数组元素后,这个数组的指针会作为临时信息(数组变量)创建到上。

区分一个数据是在上还是在上是不能靠他是引用类型还是值类型来分辨的。
例如一个int数组的元素int。他们都是固定大小的值类型int,但他们在堆上。

托管指针

什么是指针,你可以理解为:快捷方式。
就是你桌面上那个1kb大小的QQ,它记录的一个地址。
在你双击快捷方式的时候,会顺着它记录的地址,找到QQ那个500MB的安装路径,
然后打开那个真实的QQ程序。这个过程叫解指针

托管是指.Net可以控制的东西,比如分配,监视,回收,释放。
因此不同于c++的指针,c#用到的(给你用的)指针是安全的。

c#可以启用不安全代码,来使用和c++同款的不安全指针。

指针在32位程序占32bit,在64位程序占64bit。
32位程序只能用4G内存,因为同为32位的int也是能表示4G个数(正数21亿,负数21亿)。
64位程序中,指针占用双倍大小。所以天然占用更多内存。

引用类型特点

复制

一个赋值操作就是一个复制操作,数组直接用数组赋值时,就是在复制这个指针。
之后访问数组元素时,访问到的就是同一组元素。
在这里插入图片描述

只读

引用类型的变量设置只读,只是不能修改这个变量。
这个变量指向的实际数据是可以修改的。
在这里插入图片描述

比较

数组变量的值是一个指针。给变量做比较只会判断他们指向的地址是不是相同的。

int[] arr10 = new int[1];
int[] arr11 = new int[1];Console.WriteLine(arr10[0] == arr11[0]);//True
Console.WriteLine(arr10.Length == arr11.Length);//True
Console.WriteLine(arr10 == arr11);//False

引用变量

引用变量可以创建对变量的指针。对引用变量的任何操作都会解指针后对原变量进行操作。

int i1 = 6;
ref int ri1 = ref i1;//必须声明时赋值
Console.WriteLine(i1);//6
Console.WriteLine(ri1);//6,相当于访问i1
ri1 = 10;//直接赋值会作用到原变量上
Console.WriteLine(i1);//10,会被修改
Console.WriteLine(ri1);//10int[] arr12 = new int[6];
ri1 = ref arr12[0];//可以重新赋值
Console.WriteLine(arr12[0]);//0
ri1 = 50;
Console.WriteLine(arr12[0]);//50

默认值

数组创建后,它里面的元素是默认值。
对于指定的类型可以使用字面量default获得默认值。
对于没有指定的类型,可以在default后加个括号指定类型。

bool b = default;
Console.WriteLine(default(char));

默认值的逻辑是,对这个类型所占据的内存都设置为0。

  • 对于数字类型都是0
    • char也是数字类型,会被解读为一个字符编码为0的字符。
  • 对于bool类型是false
  • 对于引用类型,值为null

null也是一个字面量,表示不引用任何数据。所有的引用类型都可以使用null值。

int[][] arr13 = new int[5][];//数组是一个有效的类型,所以数组也可以有数组
for (int i = 0; i < arr13.Length; i++)
{arr13[i] = new int[6];//数组的默认值是null,无法使用
}
arr13[2][3] = 8;

null值自身可以被访问,如使用参与比较。但不能访问他的任何内容。

string s1 = null;//字符串也是引用类型
Console.WriteLine(s1 == null);//仅访问变量
Console.WriteLine(s1 == "hello");//仅访问变量
Console.WriteLine("hello".Length);//获取内容,字符串的长度
Console.WriteLine("hello"[2]);//获取内容,第3个字符
Console.WriteLine(s1.Length);//尝试获取null的内容,报错
Console.WriteLine(s1[2]);//尝试获取null的内容,报错

http://www.ppmy.cn/news/59214.html

相关文章

音频环回实验

音频环回实验 一、WM8978简介 WM8978是一个低功耗、高质量的立体声多媒体数字信号编译码器&#xff0c;它结合了一个高质量的立体声音DAC和ADC&#xff0c;带有灵活的音频线输入、麦克风输入和音频输出处理 WM8978内部有58个寄存器。每一个寄存器的地址位为7位&#xff0c;数…

22.碳交易机制下考虑需求响应的综合能源系统优化运行

说明书 MATLAB代码&#xff1a;碳交易机制下考虑需求响应的综合能源系统优化运行 注意&#xff1a;另外还有含义柔性负荷、蓄冷式空调、共享储能以及碳捕集的综合能源系统优化运行代码&#xff0c;欢迎咨询 关键词&#xff1a;需求响应 碳交易机制 日前优化调度 综合能源系统…

关于低代码开发,你是真的了解了吗?

在低代码开发已是大势所趋的今天&#xff0c;不少企业都切身感受到了低代码开发带来的便利。低代码开发平台的优势在当下数字化浪潮中&#xff0c;为企业提供了定制专属的数字化解决方案。 低代码本身没有太强的行业属性&#xff0c;这也让低代码开发平台能够更加灵活地适应不同…

pikachu靶场-Unsafe Filedownload

不安全的文件下载 文件下载功能在很多web系统上都会出现&#xff0c;一般我们当点击下载链接&#xff0c;便会向后台发送一个下载请求&#xff0c;一般这个请求会包含一个需要下载的文件名称&#xff0c;后台在收到请求后 会开始执行下载代码&#xff0c;将该文件名对应的文件…

2 行代码开启 SAST,将代码漏洞定位到具体行数

&#x1f4a1; 如何在流水线中集成与应用 SAST&#xff0c;实现自动化代码安全扫描 &#xff1f; 近日&#xff0c;在「DevSecOps软件安全开发实践」课程上&#xff0c;极狐(GitLab) 高级专业服务交付工程师欧阳希、极狐(GitLab) 后端工程师黄松&#xff0c;分享了静态安全扫描…

Android - 动画

一、概念 属性动画PeopertyAnimation&#xff1a;view的属性根据执行的动画发生真实的改变。通过不断设置 View 的属性实现。补间动画 ViewAnimation&#xff08;Tween&#xff09;&#xff1a;不改变view的位置和属性。基于 Framework的绘制转变。帧动画 DrawableAnimation&a…

【网络原理】TCP/IP协议

目录 1.应用层 2.传输层&#xff08;核心问题&#xff09; 2.1 UDP协议 2.1.2 UDP的特点 2.1.3 基于UDP的应用层协议 2.2 TCP协议&#xff08;重点内容&#xff09; 2.2.1 TCP/IP 协议含义 2.2.2 TCP协议端格式&#xff1a; 2.2.3 TCP的特点 2.3 TCP原理 2.4 确认应…

Vue3中双向数据绑定与Pinia实践+JS数据引用的循环修改问题

Vue3 Pinia VUE3虽然出了很久了&#xff0c;但是很少深入研究&#xff0c;目前项目上遇到了一些问题&#xff0c;所以做个Note解决一下疑问&#xff1a; v-bind/v-model怎么与Pinia进行结合Object/Array数据大量处理时&#xff0c;为何有的修改不生效组合API与选项API选择 (…