CSharp(十四) 基础数组
C# 中的 一维数组 是存储 相同类型 元素的 固定大小 线性集合,元素通过 单一索引 访问。里面的值使用{}而不是[]
数组的定义
声明与定义
// 方式1:声明并指定大小(元素为默认值)
int[] numbers = new int[5]; // 5个整数,默认值为0
string[] names = new string[3]; // 3个字符串,默认值为null
// 方式2:声明并初始化(指定具体值)
int[] scores = new int[] { 85, 90, 78, 92, 88 };
// 方式3:简写形式(最常用)
int[] ages = { 20, 25, 30, 35, 40 };
// 方式4:先声明,后创建
double[] prices;
prices = new double[] { 19.9, 29.9, 39.9 };
不同数据类型的数组
// 整数数组
int[] intArray = { 1, 2, 3, 4, 5 };
// 浮点数数组
double[] doubleArray = { 1.1, 2.2, 3.3 };
// 字符串数组
string[] strArray = { "Alice", "Bob", "Charlie" };
// 布尔数组
bool[] boolArray = { true, false, true, true };
// 字符数组
char[] charArray = { 'a', 'b', 'c' };
数组的访问与修改
访问元素(索引从0开始)
int[] nums = { 10, 20, 30, 40, 50 };
// 访问单个元素
Console.WriteLine(nums[0]); // 10(第一个元素)
Console.WriteLine(nums[2]); // 30(第三个元素)
Console.WriteLine(nums[4]); // 50(第五个元素,最后一个)
// 获取最后一个元素
Console.WriteLine(nums[nums.Length - 1]); // 50
修改元素
int[] nums = { 10, 20, 30, 40, 50 };
// 修改指定位置的值
nums[1] = 25; // 将第二个元素改为25
nums[3] = 45; // 将第四个元素改为45
// 现在数组变为: { 10, 25, 30, 45, 50 }
foreach (int n in nums)
{
Console.Write($"{n} ");
}
数组的遍历
for循环遍历(可读写)
int[] nums = { 10, 20, 30, 40, 50 };
for (int i = 0; i < nums.Length; i++)
{
Console.WriteLine($"索引 {i}: 值 {nums[i]}");
}
// 输出:
// 索引 0: 值 10
// 索引 1: 值 20
// 索引 2: 值 30
// 索引 3: 值 40
// 索引 4: 值 50
foreach循环遍历(只读)
int[] nums = { 10, 20, 30, 40, 50 };
foreach (int num in nums)
{
Console.WriteLine(num);
}
// 注意:foreach 中不能修改元素
// 以下代码会报错:
// foreach (int num in nums)
// {
// num = num * 2; // 错误!不能修改
// }
遍历时修改元素(使用for)
int[] nums = { 1, 2, 3, 4, 5 };
// 每个元素乘以2
for (int i = 0; i < nums.Length; i++)
{
nums[i] = nums[i] * 2;
}
// 结果: { 2, 4, 6, 8, 10 }
foreach (int n in nums)
{
Console.Write($"{n} ");
}
数组的常用属性与方法
属性
int[] nums = { 10, 20, 30, 40, 50 };
// Length:获取数组长度(元素个数)
Console.WriteLine(nums.Length); // 5
// 获取第一个和最后一个元素
Console.WriteLine(nums[0]); // 10(第一个)
Console.WriteLine(nums[nums.Length - 1]); // 50(最后一个)
静态方法 (Array类提供)
int[] nums = { 5, 2, 8, 1, 9 };
// 排序(升序)
Array.Sort(nums);
// 结果: { 1, 2, 5, 8, 9 }
// 反转数组
Array.Reverse(nums);
// 结果: { 9, 8, 5, 2, 1 }
// 查找元素索引
int index = Array.IndexOf(nums, 5); // 返回 5 的索引位置
// 二分查找(数组必须先排序)
Array.Sort(nums);
int pos = Array.BinarySearch(nums, 5); // 返回 5 的索引
// 清空数组(设为默认值)
Array.Clear(nums, 0, nums.Length);
// 结果: { 0, 0, 0, 0, 0 }
// 复制数组
int[] copy = new int[nums.Length];
Array.Copy(nums, copy, nums.Length);
// 或使用 Clone
int[] clone = (int[])nums.Clone();
数组的常见操作
增加(添加/插入)
- 末尾添加元素Append
int[] Append(int[] arr, int value)
{
int[] newArr = new int[arr.Length + 1];
Array.Copy(arr, newArr, arr.Length); // 复制原数组
newArr[arr.Length] = value; // 末尾放新元素
return newArr;
}
// 使用
int[] nums = { 10, 20, 30 };
nums = Append(nums, 40);
// 结果: { 10, 20, 30, 40 }
- 指定位置插入元素
int[] Insert(int[] arr, int index, int value)
{
int[] newArr = new int[arr.Length + 1];
Array.Copy(arr, 0, newArr, 0, index); // 复制前半段
newArr[index] = value; // 插入新元素
Array.Copy(arr, index, newArr, index + 1, arr.Length - index); // 复制后半段
return newArr;
}
// 使用
int[] nums = { 10, 20, 30, 40 };
nums = Insert(nums, 2, 25); // 在索引2插入25
// 结果: { 10, 20, 25, 30, 40 }
- 开头插入Prepend
int[] Prepend(int[] arr, int value)
{
return Insert(arr, 0, value);
}
// 使用
int[] nums = { 20, 30, 40 };
nums = Prepend(nums, 10);
// 结果: { 10, 20, 30, 40 }
删除
- 删除指定索引元素
int[] RemoveAt(int[] arr, int index)
{
int[] newArr = new int[arr.Length - 1];
Array.Copy(arr, 0, newArr, 0, index); // 复制前半段
Array.Copy(arr, index + 1, newArr, index, arr.Length - index - 1); // 复制后半段
return newArr;
}
// 使用
int[] nums = { 10, 20, 30, 40, 50 };
nums = RemoveAt(nums, 2); // 删除索引2
// 结果: { 10, 20, 40, 50 }
- 删除指定值(第一个匹配)
int[] Remove(int[] arr, int value)
{
int index = Array.IndexOf(arr, value);
if (index == -1) return arr; // 没找到,返回原数组
return RemoveAt(arr, index);
}
// 使用
int[] nums = { 10, 20, 30, 20, 40 };
nums = Remove(nums, 20); // 删除第一个20
// 结果: { 10, 30, 20, 40 }
- 删除所有匹配值
int[] RemoveAll(int[] arr, int value)
{
int count = 0;
foreach (int n in arr)
if (n != value) count++; // 统计保留个数
int[] newArr = new int[count];
int j = 0;
foreach (int n in arr)
if (n != value) newArr[j++] = n; // 复制非匹配值
return newArr;
}
// 使用
int[] nums = { 10, 20, 30, 20, 40, 20 };
nums = RemoveAll(nums, 20); // 删除所有20
// 结果: { 10, 30, 40 }
修改
- 修改指定索引
int[] nums = { 10, 20, 30, 40, 50 };
nums[2] = 35; // 索引2改为35
// 结果: { 10, 20, 35, 40, 50 }
- 批量修改
int[] nums = { 10, 20, 30, 40, 50 };
// 每个元素翻倍
for (int i = 0; i < nums.Length; i++)
{
nums[i] = nums[i] * 2;
}
// 结果: { 20, 40, 60, 80, 100 }
// 偶数位置设为0
for (int i = 0; i < nums.Length; i++)
{
if (i % 2 == 0)
nums[i] = 0;
}
// 结果: { 0, 40, 0, 80, 0 }
查找
- 按照索引查找
int[] nums = { 10, 20, 30, 40, 50 };
int first = nums[0]; // 10(第一个)
int third = nums[2]; // 30(第三个)
int last = nums[nums.Length - 1]; // 50(最后一个)
- 按照值查索引
int[] nums = { 10, 20, 30, 20, 40 };
int index = Array.IndexOf(nums, 20); // 1(第一个20的位置)
int lastIndex = Array.LastIndexOf(nums, 20); // 3(最后一个20的位置)
// 判断是否存在
bool exists = Array.IndexOf(nums, 30) >= 0; // true
- 按照条件查找
int[] nums = { 10, 25, 30, 45, 50, 65 };
// 查找第一个大于40的数
int first = Array.Find(nums, n => n > 40); // 45
// 查找所有偶数
int[] even = Array.FindAll(nums, n => n % 2 == 0); // { 10, 30, 50 }
// 查找第一个匹配索引
int idx = Array.FindIndex(nums, n => n > 40); // 3
// 判断是否存在满足条件的
bool hasEven = Array.Exists(nums, n => n % 2 == 0); // true
bool allPositive = Array.TrueForAll(nums, n => n > 0); // true
- 排序后查找(二分查找)
int[] nums = { 10, 20, 30, 40, 50 };
Array.Sort(nums); // 先排序
int pos = Array.BinarySearch(nums, 30); // 2(30的位置)
完整示例
using System;
class Program
{
static void Main()
{
int[] nums = { 10, 20, 30, 40, 50 };
Console.Write("初始: ");
Print(nums); // 10, 20, 30, 40, 50
// 增
nums = Append(nums, 60);
Console.Write("末尾+60: ");
Print(nums); // 10, 20, 30, 40, 50, 60
nums = Insert(nums, 2, 25);
Console.Write("索引2插25: ");
Print(nums); // 10, 20, 25, 30, 40, 50, 60
// 删
nums = RemoveAt(nums, 3);
Console.Write("删索引3: ");
Print(nums); // 10, 20, 25, 40, 50, 60
nums = Remove(nums, 40);
Console.Write("删40: ");
Print(nums); // 10, 20, 25, 50, 60
nums = RemoveAll(nums, 20);
Console.Write("删所有20: ");
Print(nums); // 10, 25, 50, 60
// 改
nums[1] = 99;
Console.Write("改索引1为99: ");
Print(nums); // 10, 99, 50, 60
// 查
Console.WriteLine($"\n查索引2: {nums[2]}"); // 50
Console.WriteLine($"50的索引: {Array.IndexOf(nums, 50)}"); // 2
Console.WriteLine($"第一个>50: {Array.Find(nums, n => n > 50)}"); // 60
}
static int[] Append(int[] arr, int v)
{
int[] n = new int[arr.Length + 1];
Array.Copy(arr, n, arr.Length);
n[arr.Length] = v;
return n;
}
static int[] Insert(int[] arr, int i, int v)
{
int[] n = new int[arr.Length + 1];
Array.Copy(arr, 0, n, 0, i);
n[i] = v;
Array.Copy(arr, i, n, i + 1, arr.Length - i);
return n;
}
static int[] RemoveAt(int[] arr, int i)
{
int[] n = new int[arr.Length - 1];
Array.Copy(arr, 0, n, 0, i);
Array.Copy(arr, i + 1, n, i, arr.Length - i - 1);
return n;
}
static int[] Remove(int[] arr, int v)
{
int i = Array.IndexOf(arr, v);
return i == -1 ? arr : RemoveAt(arr, i);
}
static int[] RemoveAll(int[] arr, int v)
{
int cnt = 0;
foreach (int n in arr) if (n != v) cnt++;
int[] res = new int[cnt];
int j = 0;
foreach (int n in arr) if (n != v) res[j++] = n;
return res;
}
static void Print(int[] arr)
{
Console.WriteLine(string.Join(", ", arr));
}
}
求和,平均值,最大值,最小值
int[] scores = { 85, 92, 78, 95, 88, 76, 90 };
// 手动计算
int sum = 0;
int max = scores[0];
int min = scores[0];
for (int i = 0; i < scores.Length; i++)
{
sum += scores[i]; // 累加求和
if (scores[i] > max) // 找最大值
max = scores[i];
if (scores[i] < min) // 找最小值
min = scores[i];
}
double average = (double)sum / scores.Length;
Console.WriteLine($"总分: {sum}");
Console.WriteLine($"平均分: {average:F2}");
Console.WriteLine($"最高分: {max}");
Console.WriteLine($"最低分: {min}");
数组排序(冒泡排序示例)
int[] nums = { 64, 34, 25, 12, 22, 11, 90 };
// 冒泡排序(手动实现)
for (int i = 0; i < nums.Length - 1; i++)
{
for (int j = 0; j < nums.Length - 1 - i; j++)
{
if (nums[j] > nums[j + 1])
{
// 交换
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
// 输出排序结果
Console.Write("排序后: ");
foreach (int n in nums)
{
Console.Write($"{n} ");
}
// 输出: 11 12 22 25 34 64 90
注意事项
| 注意点A | 说明 |
|---|---|
| 索引越界 | 访问 nums[5] 当长度为5时会报错(索引范围 0~4) |
| 固定大小 | 数组创建后长度不能改变 |
| 默认值 | 数值类型默认0,bool默认false,引用类型默认null |
| 类型一致 | 数组所有元素必须是相同类型 |
总结
- 定义
nt[] nums = new int[5] 或 int[] nums = { 1, 2, 3 } - 访问元素
nums[0]索引从0开始 - 遍历数组
for(可修改)或foreach(只读) - 长度
nums.Length - 常用方法
Array.Sort()、Array.Reverse()、Array.IndexOf()