数组用法以及引用类型和值类型

本文介绍了数组的基本概念,包括数组的特点、声明方式、初始化方法及如何使用。此外还详细讲解了选择排序与冒泡排序这两种经典的排序算法实现。

 1. 数组的特点:
a. 可以存储多个数据.
 b. 存储的这多个数据的类型必须是相同的. 在声明的时候指定元素的类型.
 c. 数组的长度是固定的, 在声明的时候要求必须指定数组的长度,一旦指定 这个长度就无法更改

 2. 什么时候要使用数组
 当我们有1组(这1组中有多少个数据我很确定)数据类型相同的数据需要存储的时候.我们就可以使用数组来存储.
 a. 存储的数据的类型相同.
 b. 存储的数据的个数确定.
 
 
 3. 声明数组的语法.
 元素的类型[] 数组的名称 = new 元素的类型[数组的长度];
 int[] arr = new int[3];
 a. 赋值符号左右两边的元素的类型要一致.
 b. 在声明数组的时候 必须要指定数组的长度.
 
 声明1个数组.
 int[] arr = new int[3];
 int[] 其实是1个数据类型. 读作int数组. 特别强调: int和int[]是完全不同的两种数据类型. 他们之间不兼容.
 arr是1个变量.
 new int[3];是1个表达式. 这个表达式的结果通过赋值符号赋值给arr变量.


4. 数组是如何在内存中开辟空间的()
 int[] arr = new int[3];
 a. 先在内存中声明1个int[]类型的变量arr
 b. 将这个arr变量划分成3个小空间. 划分成多少个小空间 是根据数组的长度来决定的.
 c. 这3个小空间的类型是int类型 小空间的类型是根据声明数组的时候 指定的元素的类型来决定的.
 
 数组中真正用来存储数据的是 这1个1个的小空间.
 
 5. 几个术语:
 元素:
 索引/下标
 数组的长度
 

 6. 为数组中的元素赋值.
 往数组中存储数据的时候.我们不是把数据存储给数组. 而是把数据存储给数组中的元素.
首先你要确定你想要把数据赋值给数组中的那1个元素. 通过下标来确定
 数组的名称[元素的下标] = 数据;
 
 注意两点:
 a. 为数组的元素赋值的时候 数据的类型要和元素的类型一致.
 元素的本质其实就是1个普通类型的变量.
 b. 下标不能越界. 索引超出了数组界限。
 数组的下标的范围: 0 ----> 数组的长度-1
 
 7. 修改数组中的元素的值.
 通过索引器定位元素 重新赋值即可.
 元素的本质实际上是1个普通类型的变量 其中只能存储1个值.当我们重新为其赋值的时候.
 如果这个元素中已经有值 那么新值会将老值覆盖掉.
 

 8. 取出元素的值.
 a. 我们要取的是数组的元素的值.而不是数组的值.
 当我们直接打印1个数组的时候 打印出来的是这个数组变量的类型.
 
 b. 取出数组中元素的值.
 1). 要确定你要取那1个元素的值 通过下标来确定.
 
 c. 取值的时候 所以不能越界.
 
 9. 数组的元素的默认值
 如果我们声明1个数组 没有为这个数组的元素赋值
 那么这个数组的元素是有值的.
 
 如果元素的类型是数值类型: 0
 char '\0' 'a'
 bool false
 string null
 
 10. 任意的数据类型都有数组.
 
 11. 数组的长度可以是1个,那么这个数组就只能存储1个数据.
 数组的长度也可以为0个. 那么这个数组1个数据都存储不了 这个数组就没有任何意义了.

 12. 数组的遍历
 数组名.Length可以得到这个数组的长度.
 思路: 将0到数组的长度-1 中的每1个整数遍历出来 当做数组的下标.
 for(int i=0;i<arr.Length;i++)
 {
 i是下标,所以要取出元素的值的话 要以i作为数组的下标才可以取出来.
 arr[i];
 }
  使用foreach来遍历数组中的元素.
 语法
 foreach(数据类型 变量名 in 数组的名称)
 {
 //循环体;
 }
 迭代变量:
 遍历的规则: 将数组中的元素 挨个的从第0个开始 依次的赋值给迭代变量. 赋值给迭代变量以后 就执行循环体.
循环体执行完毕之后,再将下1个元素赋值给迭代变量. 当将最后1个元素的值赋值给迭代变量以后 并执行完循环体
 就自动的结束循环.
 
 
 需要注意的地方:
 a. 迭代变量的类型要和数组中的元素的类型一致.
 b. foreach遍历出来的迭代变量的值 直接就是元素的值. 不是下标.
 c. 迭代变量的名称随便定义.
 
 for循环遍历数组 与 foreach遍历数组的 区别
 a. for循环遍历出来的是元素的下标. 如果要取元素的值的话 要将这个i当做数组的下标.
 foreach 遍历出来的直接就是元素的值. 迭代变量的值 直接 就是元素的值.
 b. for循环可以"挑三拣四" 可以从指定的元素开始遍历.
 foreach只能"从一而终" 只能把元素从头遍历到尾.
 c. for循环遍历出来的元素可以修改其值.
 而foreach不能修改迭代变量的值.
 
 其实任意的时刻都可以使用for循环来遍历.
 当我们遍历数组的时候,要从头遍历到尾.并且不会更改元素的值 这个时候可以使用foreach来遍历.

选择排序与冒泡排序

选择排序:

 

 

               for (int i = 0; i < arr.Length - 1; i++)
            {
                for (int j = 0; j < arr.Length - 1 - i; j++)
               {
                   if (arr[j] > arr[j + 1])
                   {
                        arr[j] = arr[j] + arr[j + 1];
                        arr[j + 1] = arr[j] - arr[j + 1];
                        arr[j] = arr[j] - arr[j + 1];
                    }
                }
            }

冒泡排序:

 

           int[] arr = { 12, 11, 56, 18, 19, 30, 45, 12, 34, 5, 56, 7, 68, 89, 90, 13 }; 
            for (int i = 0; i < arr.Length - 1; i++)//外层循环控制比较的轮数.
            { 
                //每1轮是如何比较的呢?
              //拿下标为i的元素  和 后面的每1个元素进行比较.i+1-----arr.Length-1
                for (int j = i + 1; j < arr.Length; j++)//这里这个循环 将i+1 到最后1个元素的值全部遍历出来 。
               {
                   if (arr[i] < arr[j])
                    {
                        int temp = arr[i];
                        arr[i] = arr[j];
                        arr[j] = temp;
                    }
                } 
            } 

            //foreach (int i in arr)
            //{
            //    Console.WriteLine(i);
            //}

 

 

转载于:https://www.cnblogs.com/sabry34126/p/3793808.html

在C#中,**数组引用类型**,尽管它们可以存储值类型元素。以下是关键点说明示例代码: ### 核心结论 1. **数组本身是引用类型**(继承自`System.Array`) 2. **元素类型决定存储方式**: - 值类型元素(如`int`、`struct`)在堆上存储实际值 - 引用类型元素(如`class`、`string`)存储引用指针 ### 示例代码 ```csharp // 示例1:数组引用类型 int[] array1 = { 1, 2, 3 }; int[] array2 = array1; // 复制引用 array2[0] = 99; Console.WriteLine(array1[0]); // 输出99(两个变量引用同一数组) // 示例2:值类型元素存储 struct Point { public int X; public int Y; } Point[] points = new Point[3]; points[0] = new Point { X = 10, Y = 20 }; Point[] pointsCopy = points; pointsCopy[0].X = 30; Console.WriteLine(points[0].X); // 输出30(修改通过引用传播) // 示例3:引用类型元素存储 string[] names = { "Alice", "Bob" }; string[] namesCopy = names; namesCopy[0] = "Charlie"; Console.WriteLine(names[0]); // 输出"Charlie" ``` ### 关键特性 1. **内存分配**: - 数组对象始终在堆上分配 - 元素存储在连续内存块中 2. **赋值行为**: ```csharp int[] a = { 1, 2 }; int[] b = a; // 只复制引用,不复制数据 ``` 3. **性能影响**: - 传递大数组给方法时只会复制引用(4/8字节) - 修改元素会影响所有引用该数组的变量 ### 与值类型的对比 ```csharp // 值类型示例 struct MyStruct { public int Value; } MyStruct s1 = new MyStruct { Value = 10 }; MyStruct s2 = s1; // 完整复制 s2.Value = 20; Console.WriteLine(s1.Value); // 仍为10(不受影响) ``` ### 特殊注意事项 1. **`ref`返回数组元素**: ```csharp static ref int GetElementRef(int[] arr, int index) => ref arr[index]; // 允许直接修改数组元素的值类型 ``` 2. **数组协变**(仅限引用类型数组): ```csharp object[] objArray = new string[] { "test" }; // 合法 // int[] intArray = new long[] { 1L }; // 编译错误(值类型不协变) ``` 3. **`Array.Copy`与引用处理**: ```csharp string[] src = { "original" }; string[] dest = new string[1]; Array.Copy(src, dest, 1); // 复制引用,不复制对象 ``` ### 最佳实践建议 1. 需要独立副本时使用`Array.Clone()`或`Array.Copy` 2. 处理大型数组时注意引用语义带来的副作用 3. 考虑使用`Span<T>`或`Memory<T>`进行更安全的内存操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值