数组 (赋值 初始化 值传递和引用传递 遍历 可变参数 )

这篇博客介绍了数组的概念,包括为什么需要学习数组,数组的声明、赋值和使用。重点讲解了数组的初始化,包括静态初始化和动态初始化的区别,并探讨了值传递和引用传递的原理。此外,还讨论了如何使用foreach遍历数组,以及可变参数的使用和特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数组
为什么需要学习数组? 存储多个变量的容器

数组的概述: 一组存储相同数据类型的容器
数组的本质也是一个变量,用来存储一组变量的容器

格式: 数据类型[] 数组名 = new 数据类型[数组的长度]; // Java写法
变式: 数据类型 数组名[] = new 数据类型[数组的长度]; // C语言写法

	这里的数据类型可以是八大基本数据类型也可以是引用数据类型
	数组名满足变量名的命名规范,一般都是复数
	new: 在堆区分配内存空间
	数组的长度: 表示数组可以存放多少个连续的变量

变量的三要素: 1.声明 2.赋值 3.使用
数组的声明:
表示告诉计算机开辟多大的连续的内存空间

数组的赋值:
地址传递

数组的使用: 访问数组中的元素

如何来访问数组中的元素: 通过下标、索引
数组名[索引]
索引范围 [0,数组的长度)

ArrayIndexOutOfBoundsException
异常名称: 数组索引越界异常
产生原因: 访问了不存在的索引
解决办法: 检查索引是否在 [0,数组的长度) 的范围内

NullPointerException
异常名称: 空指针异常
产生原因: 引用类型的变量没有 new,就访问了对象的成员或者访问了数组的元素
解决办法: 找到错误代码对应的那一行,观察哪些是引用类型,再观察这个引用类型有没有new

数组的初始化
  • 1.静态初始化: 初始化的同时给数组的每一个元素赋值,不需要指明数组的长度,系统根据元素的个数动态计算数组的长度
    格式:
    格式一:数据类型[] 数组名 = {元素1, 元素2, 元素3, … , 元素n};
    格式二:数据类型[] 数组名 = new 数据类型[] {元素1, 元素2, 元素3, … , 元素n};
    有了格式一为什么有格式二? --> 在传递参数的时候,如果是匿名数组必须使用格式二
  • 2.动态初始化: 初始化的同时由系统为每一个元素赋值,必须指明数组的长度,赋值的特点满足堆区的默认值特点
    堆区中每个变量都有默认值
    byte short int long 默认值 0
    float double 默认值 0.0
    char 默认值 ‘\u0000’ 就是一个空字符
    boolean 默认值 false
    引用类型 默认值 null
    格式: 数据类型[] 数组名 = new 数据类型[数组的长度]; // Java写法
    变式: 数据类型 数组名[] = new 数据类型[数组的长度]; // C语言写法
面试题: 静态初始化和动态的初始化的区别?
值传递和引用传递

方法调用的时候:
形式参数可以是如下类型
八大基本数据类型: 数值本身
引用数据类型: 地址
值传递本质传递的是数值,引用传递传递的是地址

foreach遍历 数组和集合的专属迭代器

for循环的简化
擅长遍历
语句格式:
for(元素类型 元素变量 : 遍历对象){
使用元素变量
}

对比二者的区别:
1.foreach相比普通for,更简洁
2.foreach没有索引,普通for有索引,可以自定义索引
3.foreach的本质还是普通for
int ai[];
int k = (ai = arr).length;
for (int j = 0; j < k; j++)
{
int i = ai[j];
System.out.println(i);
}

可变参数

为什么需要有可变参数? – 针对参数的类型一致,但是个数不一致的情况使用

格式:
参数类型… 变量名

可变参数的特点:
1.可变参数本质是数组
2.可变参数的 … 可以出现在 参数类型 和 变量名的 任意位置
3.可变参数必须出现参数列表的最后

动态初始化的快速初始化方式
1.通过键盘输入

2.通过随机数

public class ArrayDemo07 {
	public static void main(String[] args) {
		// 1.通过键盘输入
		Scanner input = new Scanner(System.in);
		int[] arr = new int[5];
		
		/*for (int i = 0; i < arr.length; i++) {
			System.out.print("请输入第" + (i+1) + "个数: ");
			arr[i] = input.nextInt();
		}
		
		System.out.println(Arrays.toString(arr));*/
		
		//  2.通过随机数
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int) (Math.random() * 100);
		}
		System.out.println(Arrays.toString(arr));
	}
}
<think>嗯,用户问的是在C语言中如何将一个可变数组初始化为一个。首先,我需要确认几个关键点。C语言中的可变数组通常指的是动态分配的内存,比如使用malloc或calloc创建的数组。静态数组的大小在编译时确定,而动态数组的大小在运行时确定,所以初始化方法可能不同。 然后,用户想要将整个数组初始化为同一个。这需要分情况讨论。如果是静态数组,可以在声明时用初始化列表,但只能对所有元素予相同的初始,不过对于较大的数组,手动写每个元素的不现实。这时候可能需要用循环来赋值。 如果是动态数组,也就是通过malloc或calloc分配的,calloc会自动初始化为零,但如果需要其他,必须手动赋值。这时候同样需要循环遍历每个元素,逐个赋值。 另外,考虑使用memset函数,但需要注意memset按字节设置,适用于初始化为0或某些特定字节模式的情况。如果数组元素类型不是char,比如int,用memset可能无法正确初始化,比如设置为1会导致每个字节为0x01,对于int来说实际是0x01010101,这可能不是用户想要的。 用户可能需要的是通用的方法,无论数组类型是静态还是动态。所以可能需要分步骤说明:声明时初始化、循环赋值、使用memset的注意事项,以及动态数组的处理。 还要注意C99引入的指定初始化特性,可以在声明时对部分元素赋值,但可能不适用于所有情况。此外,对于较大的静态数组,GCC可能有扩展语法允许初始化所有元素,但这不是标准C,需要提醒用户可移植性问题。 可能用户对可变数组的理解有误,可能指的是动态分配的数组,或者VLA(变长数组)。VLA在C99之后支持,但不能在声明时初始化,所以必须用循环或memset。 需要总结几种方法,并指出各自的适用场景注意事项,确保用户了解不同情况下的正确做法,避免常见的错误,比如误用memset导致的错误。</think>在C语言中,要将一个可变数组(动态分配的数组或变长数组)的所有元素初始化为指定,可以通过以下步骤实现: --- ### 方法1:静态数组初始化(适用于固定大小数组) ```c // 声明时直接初始化所有元素为0 int static_array[5] = {0}; // 仅第一个元素显式设为0,剩余元素自动补0 // 注意:此方法只能初始化为0,不能其他 ``` --- ### 方法2:动态数组的循环赋值(通用方法) ```c #include <stdlib.h> int main() { int size = 10; int *dynamic_array = malloc(size * sizeof(int)); // 用循环为每个元素赋值 for (int i = 0; i < size; i++) { dynamic_array[i] = 42; // 初始化为42 } free(dynamic_array); return 0; } ``` --- ### 方法3:使用`memset`(仅适用于字节级初始化) ```c #include <stdlib.h> #include <string.h> int main() { int size = 10; int *dynamic_array = malloc(size * sizeof(int)); // 将内存块每个字节设为0x00(即全0) memset(dynamic_array, 0, size * sizeof(int)); free(dynamic_array); return 0; } ``` ⚠️ 注意:`memset`按字节操作,若初始化非0(如1),会导致错误结果: $$ \text{例如} \quad \text{memset(arr, 1, size)} \Rightarrow \text{每个int的字节为0x01010101} $$ --- ### 方法4:变长数组(VLA)的初始化(C99+) ```c void init_vla(int size) { int vla[size]; for (int i = 0; i < size; i++) { vla[i] = 42; // 必须通过循环赋值 } } ``` --- ### 关键总结 1. **动态数组必须手动初始化** - 使用`malloc`/`calloc`分配的数组不会自动初始化(除非用`calloc`初始化为0) - 必须通过循环或`memset`(仅限0或特定字节模式)赋值 2. **效率对比** - `memset`比循环更快,但仅适用于特定 - 非0初始化推荐用循环 3. **代码规范建议** ```c // 推荐写法:通过宏定义初始 #define INIT_VALUE 42 for (int i = 0; i < size; i++) { arr[i] = INIT_VALUE; } ``` --- ### 常见错误 ```c // 错误1:尝试初始化非0 int arr[5] = {42}; // 只有第一个元素是42,其余为0 // 错误2:对动态数组使用静态初始化语法 int *arr = malloc(5 * sizeof(int)); arr = {1,2,3,4,5}; // 语法错误 ``` 通过以上方法,可以根据实际需求选择最合适的初始化方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值