C语言的数组
你好,这是我最近对于C语言数组的学习心得和错题解析,如果有任何错误欢迎指正,会持续更新,欢迎交流,希望给你起到参考作用,我们一起学习,一起进步!
何为数组
数组是一组元素集,
大小固定不可变。
索引从零开始算,
存储数据不费力。
遍历用循环来,
访问元素轻松做。
增删改查操作多,
数组用得心应手。
一维数组
简单来说就是只有一组元素
一维数组的创建
基本语法结构如下
type arr_name[常量值];
- type 是指 数组中存放数据的类型,可以是char、short、int等,也可以是自定义类型
- arr_name 是指 数组名的名字,符合命名规则即可
- [] 中的常量值用来指定 数组的大小,根据实际情况确定
举一些例子
int English[15];//存放班上15个人的英语成绩
double score[15];//平均成绩
char arr[10];//字符数组
一维数组的初始化
在数组创建的时候,我们需要指定一些初始值
那该如何初始化呢?
一般使用大括号,并将数据放在大括号中
//完全初始化
int arr[3]={1,2,3};
//不完全初始化
int arr2[5] = {1};//第一个元素初始化为1,剩余元素默认初始化为0
先来看几道错题
int y = 2;
int x[2];
x[0] = y;
y = x[1]*10;
执行以上程序段后变量y的值为
我的答案是20
正确答案是 不定值 ,因为x[1]未初始化,具有不确定的值
再看下一道
有定义int a[10]={0,2,4};, 则数组a在内存中所占字节数是
我的答案是12
正确答案是40
注意看这里是不完全初始化,因为数组a有10个整数,所以每个整数占4个字节, 10*4=40
再来一道
#define M 2
#include<stdio.h>
void main()
{
int a[5] = { 0 }, i;
for (i = 0; i < M; i++)
a[i] = a[i] + 1;
printf("%d\n", a[M]);
}
以上程序运行后,输出结果为
我的答案是2
正确答案是0
这里主要考察的就是 不完全初始化 以及 for循环 宏定义
a[5]里以一个元素为0,其余元素也默认初始化为0
for循环开始,迭代两次
a[0]=a[0] + 1 = 1,a[1]=a[1] + 1 = 1;a[2]=a[M] = 0
一维数组的使用
首先我们要明白,数组是有下标的,下标从 0 开始,若有n个元素,则最后一位元素下标为 n-1
举个例子
#include<stdio.h>
int main()
{
int arr[8] = {1,2,3,4,5,6,7,8};
printf("%d\n",arr[7]);//8
printf("%d\n",arr[1]);//2
return 0;
}
其中 [ ] 叫做下标引用操作符
除了单个元素访问之外,我们还可以访问整个数组的内容,该如何操作呢?
#include<stdio.h>
int main()
{
int arr[8] = {1,2,3,4,5,6,7,8};
int i = 0;
for(i = 0; i<8 ; i++)
{
printf("%d\n",arr[i]);
}
return 0;
}
知道如何访问后,我们也要明白如何根据自己的需求,给数组输入想要的数据
#include<stdio.h>
int main()
{
int arr[8] = {1,2,3,4,5,6,7,8};
int i = 0;
for(i=0; i<8 ; i++)
{
scanf("%d",&arr[i]);
//注意这里需要取地址,arr[i]是数组中的元素
//arr(数组名)才代表一个地址
}
for(i=0; i<8 ; i++)
{
printf("%d",arr[i]);
}
return 0;
}
一维数组在内存中的存储
想知道数组在内存中如何存储就需要依次打印数组元素的地址进行观察
#include<stdio.h>
int main()
{
int arr[8] = {1,2,3,4,5,6,7,8};
int i = 0;
for(i=0;i<8;i++)
{
printf("&arr[%d] = %p\n",i,&arr[i]);
//%p为打印地址,之后在指针章节我们也会学习到
}
return 0;
}
这里显示的地址是16进制的(关于进制转换之后也会出),即 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,逢16进1,注意观察后两位,每一位相差4,由此我们可以得出
- 数组在内存中是连续存放的
- 随着数组下标增长,地址也由小到大(由高到低)变化
sizeof计算数组元素个数
在遍历数组的时候如果我们想知道数组中元素的个数,我们应该怎么办呢?
sizeof可以计算类型或变量大小,自然可以算出数组元素个数
示例如下:
#include<stdio.h>
int main()
{
int arr[10] = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
prinft("%d\n",sz);
return 0;
一维数组 好题&错题汇总:
反序输出
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d",&n);//先输入一个整数
//不完全初始化数组,并给出足够的空间
int arr[1000]={0};
//第一次遍历
for(int i = 0;i < n;i++)
{
scanf("%d",&arr[i]);//输入n个数
}
//第二次遍历
for(int j = n - 1;j >= 0;j--)
{
if(i < n - 1)
{
printf(",");//控制格式
printf("%d",arr[i]);//打印数组
}
}
return 0;
}
逆序输出
#include<stdio.h>
int main()
{
int i = 0;
//不完全初始化一个长度为10的数组
int arr[10] = {0};
//第一次遍历
for(i = 0;i < 10;i++)
{
//输入10个数字,储存到数组arr中
scanf("%d",&arr[i]);
}
//第二次遍历
for (i = 0; i < 10; i++)
{
//将输入的数字打印出来
printf("%d", arr[i]);
//控制格式
if (i < 9)
{
printf(",");
}
}
printf("\n");
//第三次遍历,改变j的下标,逆序输出
for (int j = 9;j >= 0; j--)
{
printf("%d", arr[j]);
//控制格式
if (j > 0)
{
printf(",");
}
}
return 0;
}
实际问题:8号选手参加校园歌手大赛,编程读入20个整数(70-100之间)并存入数组中做为20个评委的打分,请按题目要求编程实现输出样例要求的功能(最后得分为去掉最高分和最低分后的平均分)。
#include<stdio.h>
int main()
{
//不完全初始化一个长度为20的数组
int arr[20] = { 0 };
//第一次遍历,输入20个数字
for (int i = 0; i < 20; i++)
{
scanf("%d", &arr[i]);
}
//将数组内第一个值赋给max,min,sum
int max = arr[0];
int min = arr[0];
int sum = arr[0];
//第二次遍历
for (int i = 1; i < 20; i++)
{
//依次比较,找出最大值
if (arr[i] > max)
{
max = arr[i];
}
//找出最小值
if (arr[i] < min)
{
min = arr[i];
}
//将数组内的数都加起来
sum += arr[i];
}
double fin = 0;
fin = (sum - max - min) / 18.0;
printf("去掉一个最高分:%d分\n", max);
printf("去掉一个最低分:%d分\n", min);
printf("8号选手最后得分:%.3lf分", fin);
return 0;
}
二维数组
一维数组的元素都是内置类型的,若把 一维数组作为元素,这时候就是二维数组 ,我们接着这个逻辑,若我们把二维数组作为元素得到的就是三维数组,二位数组及以上就是多维数组
画个图来理解一下
二维数组的创建
基本语法格式如下
type arr_name[常量值][常量值];
要求类似于一维数组,我们举个例子来体会一下
int main()
{
int term[3][5];
return 0;
}
二维数组的初始化
举例来看
int arr1[3][5] = {1,2,3};//不完全初始化
int arr2[3][5] = {{1,2},{3,4},{5,6}};//不完全初始化 用{}控制其所处位置
int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};//完全初始化
int arr4[3][ ] = {1,2,3,4,5,6};//省略列
int arr5[ ][5] = {1,2,3,4,5,6};//省略行
看看运行结果
无法运行,报错了,这也证明了 能省略行,但不能省略列 因为 二维数组中的元素通常是 按行排列 的
我们再来看看修正后的调试的结果
二维数组的使用
类比于一维数组,二维数组也是通过下标访问的
二维数组的下标
行下标从 0 开始,列下标也从 0 开始
还是举例来看
#include<stdio.h>
int main()
{
int arr[3][5] = { 0 };
//输入
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
scanf("%d", &arr[i][j]);
}
}
//输出
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 5; j++)
{
printf("%d", arr[i][j]);
}
}
return 0;
}
调试结果如下
这里注意 数组名是地址,具体的涉及下标的即为元素,这里我们先浅说,到了指针章节再具体展开
二维数组在内存中的存储
二维数组在内存中是 连续存放 的,可以结合我们上一个例子来看
变长数组
- 在C99标准之前,数组在创建的时候,数组的大小的指定只能使用常量或常量表达式
- C99之后,C语言引入变长数组的概念,使得数组的大小可以使用变量来指定
- 但是 VS2022 不支持变长数组
- 变长数组不能初始化
- 变长数组是指:数组的大小是可以通过变量来指定的,而不是说数组的大小是可变的, 数组的大小一旦确定就不能再变化了