一位数组与二维数组
1 数组的概念
在程序设计中,为了方便处理数据把具有相同类型的若干变
量按有序形式组织起来,这些按序排列的同类数据元素的集合
称为数组
在C语言中,数组属于构造数据类型。一个数组可以分解为多
个数组元素,这些数组元素可以是基本数据类型或是构造类
型。因此按数组元素的类型不同,数组又可分为数值数组、
字符数组、指针数组、结构数组等各种类别。本章介绍数值
数组和字符数组
数组的特点:
数组中的元素是连续的(元素的内存地址连续)
同一个数组所有的成员都是相同的数据类型
2 一维数组
2.1 定义
一维数组的定义语法规则
数据类型 数组名[常量表达式];
说明:
-
数组名的命名规范必须满足“标识符的命名规范”
-
方括号中的常量表达式就是数组的长度,也就是数组中存
储元素的个数
示例:
int a[10]; 说明整型数组a,有10个元素。
float b[10], c[20]; 说明实型数组b,有10个元素,
实型数组c,有20个元素
char ch[20]; 说明字符数组ch,有20个元素
2.2 使用
使用下标访问数组中的元素:
-
下标的值必须为整形常量/变量
-
下标的值从0 开始 到数组长度-1 结束
-
注意:如果使用的下标值大于或者等于数组长度,程序仍然可以编译通过,但是运行结果是未知的!
案例:
#include <stdio.h>
int main()
{
int a[10];//定义了一个数组,名字叫a,有10个成
员,每个成员都是int类型
int i = 0;
for (i = 0; i < 10; i++)
{
a[i] = i; //给数组赋值
}
//遍历数组,并输出每个成员的值
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
2.3 初始化
给数组赋值的方法除了用赋值语句对数组元素逐个赋值外,
还可采用初始化赋值和动态赋值的方法
案例:
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//定义一个数组,同时初始化所有成员变量
int a[10] = { 1, 2, 3 };//初始化前三个成员,后面所有元素都设置为0
int a[10] = { 0 };//所有的成员都设置为0
//[]中不定义元素个数,定义时必须初始化
int a[] = { 1, 2, 3, 4, 5 };//定义了一个数组,有5个成员
注意:局部数组如果不初始化,内容为随机值
2.4 元素的存储方式
2.4.1 字符数组
案例:
char ch[] = {'A', 'B', 'C','D'};
int i;
for (i = 0; i < 4; i++)
printf("%p ", &ch[i]);
printf("\n");
2.4.2 整型数组
案例:
int a[] = {1, 2, 3, 4};
int i;
for (i = 0; i < 4; i++)
printf("%p ", &a[i]);
printf("\n");
提示:
通过sizeof(数组名)可以求数组在内存中占用的字节数
案例:
char a[5];
int b[5];
printf("a sizeof = %d, a sizeof = %d", sizeof
(a), sizeof (b));
思考:假如有一维数组a,我们不知道数组中元素的数据类型,求数组a的长度
len = sizeof(a)/sizeof(a[0])
2.5 练习
//求数组中所有元素的和
#include<stdio.h>
int main()
{
int a[10]={1,2,3,4,5,6,7};
int sum=0,i=0;
for(i=0;i<7;i++)
{
sum+=a[i];
}
printf("sum=%d\n",sum);
}
//求数组中的最大值和最小值以及平均值(不考虑浮点数)
#include<stdio.h>
int main()
{
int a[8]={1,4,5,6,7,3,43,86};
int max=a[0];
int min=a[0];
int avg=0,sum=0;
int len=sizeof(a)/sizeof(a[0]);
for(int i=0;i<len;i++)
{
if(max<a[i])
{
max=a[i];
}
if(min>a[i])
{
min=a[i];
}
sum+=a[i];
}
avg=sum/len;
printf("max=%d,min=%d,avg=%d\n",max,min,avg);
}
//定义一个整型数组,长度随意,内容随意,判断该数组是
//否为升序数组,如果是打印yes,不是打印no
#include<stdio.h>
int main()
{
int a[10]={1,2,3,4,5,6,7,8,10,10};
int len=sizeof(a)/sizeof(a[0]); //计算数组长度
int flag=1; //假设数组是升序数组
int i=0;
for(i=0;i<10;i++)
{
if(a[i]>a[i+1])
{
flag=0;
break;
}
}
if(flag)
{
printf("该数组是升序数组");
}
else
{
printf("该数组不是升序数组");
}
}
//一维数组的逆置
#include<stdio.h>
int main()
{
int a[10]={1,-2,3,-4,5,-6,7,-8,9,-10};
int i=0;
int len=sizeof(a)/sizeof(a[0]);
int j=len-1;
while(i<j)
{
a[i]^=a[j]; //异或 不使用中间变量交换两个数
a[j]^=a[i];
a[i]^=a[j];
j--;
i++;
}
for(i=0;i<10;i++)
{
printf("%d ",a[i]);
}
return 0;
}
删除一维数组中指定的元素
#include<stdio.h>
int main()
{
int a[10]={1,2,13,532,64,83,64,45,34,65};
int i=0;
int j=0;
int num;
printf("请输入要删除的数:");
scanf("%d",&num);
for(i=0;i<10;i++)
{
if(num==a[i])
{
for(j=i;j<9;j++)
{
a[j]=a[j+1];
}
a[9]=0;
break;
}
}
if(i==10)
{
printf("没有找到要删除的数");
}
else
{
for(i=0;i<9;i++)
{
printf("%d ",a[i]);
}
}
return 0;
}
//将一个无序一维数组的所有的奇数放前面,所有的偶数放
//后面
#include <stdio.h>
int main() {
int a[8] = {1, 2, 3, 4, 5, 6, 7, 8};
int len = sizeof(a) / sizeof(a[0]);
int i = 0;
int j = len - 1;
while (i < j) {
while (a[i] % 2 == 1 && i < j) {
i++;
}
while (a[j] % 2 !=1 && i < j) {
j--;
}
if (i < j) {
a[i]^=a[j];
a[j]^=a[i];
a[i]^=a[j];
}
}
for (i = 0; i < len; i++) {
printf("%d ", a[i]);
}
return 0;
}
3 二维数组
3.1 定义
在实际应用中有许多数据是二维的,例如棋盘是有多行多
列,如果使用C语言描述一个棋盘我们需要使用二维数组
定义二维数组的语法规则
数据类型 数组名[常量表达式1] [常量表达式2];
说明:
我们可以将二维数组当作一个有行有列的二维矩阵
常量表达式1代表矩阵的行数
常量表达式2代表矩阵的列数
二维数组可以理解为由 “常量表达式1”个一维数组所组成的
案例:
//数组a是一个有3行4列的二维数组,数组中元素的数据类型为
int
int a[3] [4];
3.2 使用
二维数组也同样通过下标对数组中的元素进行访问,与一
维数组不同的是,二维数组元素的访问需要使用两个下标
行下标的值从0 开始到“常量表达式1”-1
列下标的值从0开始到“常量表达式2”-1
通过双重循环访问二维数组中的元素
示例:
#include <stdio.h>
int main()
{
int a[2][3];
int m, n;
//一行一行访问
for (m = 0; m < 2; m++)
{
for (n = 0; n < 3; n++)
{
printf("%d ", a[m][n]);
}
printf("\n");
}
//一列一列访问
for (m = 0; m < 2; m++)
{
for (n = 0; n < 3; n++)
{
printf("%d ", a[n][m]);
}
printf("\n");
}
return 0;
}
3.3 初始化
3.3.1分段赋值
//分段赋值 int a[3][4] = {{ 1, 2, 3, 4 },{ 5,
6, 7, 8, },{ 9, 10, 11, 12 }};
int a[3][4] =
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8, },
{ 9, 10, 11, 12 }
};
3.3.2 连续赋值
//连续赋值
int a[3][4] = { 1, 2, 3, 4 , 5, 6, 7, 8, 9,
10, 11, 12 };
3.3.3 部分赋值
//可以只给部分元素赋初值,未初始化则为0
int a[3][4] = { 1, 2, 3, 4 };
3.3.4 0值初始化
//所有的成员都设置为0
int a[3][4] = {0};
3.3.5 不指定行数
//[]中不定义元素个数,定义时必须初始化
int a[][4] = { 1, 2, 3, 4, 5, 6, 7, 8};
3.3.6 不能不指定列数
int a[4][] = { 1, 2, 3, 4, 5, 6, 7, 8};//错误
的初始化
二维数组中元素在内存中的存储
在内存中并不存在二维数组,二维数组实际的硬件存储器
是连续编址的,也就是说内存中只有一维数组,即放完一
行之后顺次放入第二行,和一维数组存放方式是一样的
3.4练习
//求二维数组每一行的最大值并且打印出最大值的列号, 求每
//一列的最大值并且打印所在的行号
#include<stdio.h>
int main()
{
int a[2][3]={{1,2,3},
{4,5,6}
};
int i,j,flag=0;
int max,max1=0;
for(i=0;i<2;i++)
{
max=a[i][0];
for(j=0;j<3;j++)
{
if(max<a[i][j])
{
max=a[i][j];
flag=j;
}
}
printf("第%d行的最大值为%d,在第%d列:\n",i,max,flag);
}
for(j=0;j<3;j++)
{
max=a[0][j];
for(i=0;i<2;i++)
{
if(max1<a[i][j])
{
max1=a[i][j];
flag=i;
}
}
printf("第%d列的最大值为%d,在第%d行:\n",j,max1,flag);
}
return 0;
}
//求二维数组a[4] [4]的对角线之和
#include<stdio.h>
int main()
{
int a[4][4]={{1, 2, 3, 4},
{5, 6, 7, 8},
{9 ,10,11,12},
{13,14,15,16}};
int i,j,sum=0;
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
if(i==j||i+j==3) //两条对角线
{
sum+=a[i][j];
}
}
}
printf("sum=%d",sum);
return 0;
}