C语言修行中(3)数组

本文详细探讨了数组的基本概念、声明、初始化规则,包括不同情况下的初始化错误处理、元素访问与修改、数组越界问题,以及多维数组、字符数组和内存赋值技巧。重点讲解了数组整体赋值和字符数组的特殊性,以及如何避免常见陷阱。
摘要由CSDN通过智能技术生成

目录

数组的概念

声明数组

数组初始化

初始化列表的元素数量与数组长度不符

(1)初始化列表短于数组长度

(2)初始化列表长于数组长度

(3)由初始化列表来决定数组的长度

访问数组内的元素

修改数组元素

数组越界

数组整体赋值

(2)内存赋值(memcpy函数)

多维数组

字符数组

声明字符数组

访问字符数组

字符串结尾标记\0

输入字符数组


数组的概念

数组,是由一系列类型相同的数据对象依次排列组合而成。

组成数组的数据对象,被称作数组的元素

声明数组


元素类型 数组名[元素数量];


例如:

char c[123];

int n[456];

float f[789];

数组初始化


元素类型 数组名[元素数量n]={元素1,元素2,...元素n};


例如:

int arr[10]={1,2,3,4,5,6,8,9,0};

声明了由10个int类型数据对象组成的数组,并将它们分别初始化为1,2,3,4,5,6,7,8,9,0。

数组初始化时,等号右边被称为初始化列表,写明了数组的元素分别需要被初始化成哪些值。

初始化列表的元素数量与数组长度不符

(1)初始化列表短于数组长度

例如:int arr[10]={1,2,3,4,5};

那么将用0初始化剩下的元素。打印出来的结果为1,2,3,4,5,0,0,0,0,0

又例如:如果初始化列表为空,即int arr[10]={}; ,那么所有的元素都将被填0。

(2)初始化列表长于数组长度

例如:int arr[10]={1,2,3,4,5,6,7,8,9,10,11};

那么代码是无法编译通过的。

(3)由初始化列表来决定数组的长度

例如:int arr[]={1,2,3,4,5,6,7};

访问数组内的元素


数组名[下标]


数组的下标是从0开始。0为下标的话,访问到的是数组的第一个元素。

也可以用for循环访问数组的每一个元素:

 int arr[6] = { 1,2,3,4,5,6 };
 for (int i = 0; i < 6; i++)
 {
     printf("%d ", arr[i]);
 }
 ​
 结果为
 1 2 3 4 5 6

修改数组元素

 int arr[5] = {};//声明一个数组,将全部元素初始化为0
 printf("%d\n", arr[2]);//打印数组的第三个元素
 arr[2] = 123;//把数组的第三个元素赋值
 printf("%d\n", arr[2]);//再次打印
 ​
 结果为
 0
 123

数组越界

如果一个数组只有10个元素,但是访问或修改了这十个元素以外的元素,那么程序很有可能被异常终止。例如:

 int arr[5] = {};
 printf("%d\n", arr[10]);
 ​
 结果为
 -858993460

C语言编译器不会检查数组是否越界,所以在编写过程中需要格外注意。

数组整体赋值

(1)使用循环为单个元素赋值

 int arr1[5] = {};
 int arr2[5] = { 1,2,3,4,5 };//两个已初始化的数组
 for (int i = 0; i < 5; i++)
 {
     arr1[i] = arr2[i];
 }

(2)内存赋值(memcpy函数)


memcpy(目标数组,原始数组,需要赋值多少字节数据);


假如第三个参数需要复制的字节数为N,则

原始数组的大小不能小于N,否则将复制无意义内容

目标数组的大小不能小于N,否则没有足够的空间存放数据。

 #include <stdio.h>
 #include <memory.h>//引入头文件
 int main()
 {
     int arr1[5] = {};
     int arr2[5] = { 1,2,3,4,5 };
     memcpy(arr1, arr2, sizeof(arr1));
     return 0;
 }

多维数组

即数组来作为元素。

int A[3][2] = { {1,2},{3,4},{5,6} };//声明一个二维数组
int B[4][3] = { 1,2,3,1,2,3,1,2,3 };//也可以省略内层花括号
printf("%d %d\n", A[0][1], B[3][2]);//访问多维数组的某个元素

结果为
2 0

//一般使用嵌套循环修改和访问每个元素
for (int i = 0; i < 3; i++)
{
	for (int j = 0; j < 2; j++)
	{
		A[i][j] = A[i][j] * 2;
	}
}
for (int i = 0; i < 3; i++)
{
	for (int j = 0; j < 2; j++)
	{
		printf("%d ", A[i][j]);
	}
	printf("\n");
}

结果为
2 4
6 8
10 12

字符数组

声明字符数组

(1)

char str[10]={'H','E','L',,'L','O'};

(2)

char str[10]="HELLO";

访问字符数组

printf函数的第一个参数可以是字符串,所以可以直接把数组作为printf的第一个参数:

char str[6] = "HELLO";
printf(str);

或者转换规范%s可以做字符串的占位符:

char str[6] = "HELLO";
printf("%s", str);

字符串结尾标记\0

在使用字符串常量时,会自动在字符串末尾添加\0,用于标记字符串结束。然而在使用字符串数组时,有些情况不能保证字符串末尾有\0,因此需要格外注意。

(1)初始化列表长度小于数组长度

char str[10] = "HELLO";
printf(str);

结果为
HELLO

前五个元素被填充为“HELLO”,后五个元素被填充为“0”,因为第六个元素是0,所以数组中的字符串正常结尾。

(2)初始化列表长度等于数组长度

char str[5] = "HELLO";
printf(str);

没有位置存放\0,数组中的字符串无法正常结尾,printf将继续打印数组外的元素,导致出现乱码,直到\0出现。

(3)初始化列表长度大于数组长度,则无法编译

输入字符数组

scanf函数会自动在输入的字符数组后面加上\0,输入的字符串可以正常结尾。


欲要看究竟,处处细留心。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值