数组
概念:数组是一些具有相同类型的数据的集合,(数组中数据按照一定的顺序排列存放,用不同的序号即下标来区分数组中各元素)
定义:类型名 数组名[数组长度]
(类型名指定数组中每个元素的类型,数组名是数组变量的名称,必须是一个合法的标识符;数组长度是一个整型常量表达式,指定数组的大小)
※C语言规定:数组名表示该数组所分配连续内存空间中的第一个单元的地址,即首地址.(由于数组空间一经分配之后再运行过程中不会改变,因此数组名是一个地址常量,不允许修改)
引用:数组名[下标]
(下标可以是整型表达式,合理取值范围是[0,数组长度-1])
★注:数组下标从0开始,下标不能越界
※C语言规定:只能引用单个的数组元素,而不能一次引用整个数组
一维数组
初始化:类型名 数组名[数组长度]={初值表}
/*※C语言规定:只有静态存储的数组才能初始化,但一般的C编译系统都允许对动态存储的数组赋初值*/
int a1[5];
/*静态存储的数组如果没有初始化,系统自动给所有的数组元素赋0*/
static a2[5];
- 对所有的元素赋初值(如果对所有的元素赋了初值,就可以省略数组长度)
int b1[5]={1,2,3,4,5};
static b2[]={1,2,3,4,5};
- 对部分元素初始化不能省略数组长度
auto int c1[5]={1,2,3};
static int c2[5]={1,2,3};
- 利用字符常量初始化
int d1['A']={1,2,3,4,5}; //相当于的[65]
- 数组元素全部初始化为0
int d2[5]={0};
printf("未初始化的数组:\n");
printf("动态数组:\n");
for(i=0;i<5;i++)
printf("%d ",a1[i]);
printf("\n\n");
printf("静态数组:\n");
for(i=0;i<5;i++)
printf("%d ",a2[i]);
printf("\n※※※※※※※※※※※※※※※※※※※※※※※※※※※※\n\n\n");
printf("3.1:对所有数组元素初始化(动态数组和静态数组结果一样):\n");
printf("动态数组:\n");
for(i=0;i<5;i++)
printf("%d ",b1[i]);
printf("\n数组大小=%d\n",sizeof(b1));
printf("\n\n");
printf("省略了数组长度的静态数组:\n");
for(i=0;i<5;i++)
printf("%d ",b2[i]);
printf("\n数组大小=%d\n",sizeof(b2));
printf("\n※※※※※※※※※※※※※※※※※※※※※※※※※※※※\n\n\n");
printf("3.2:对数组部分元素初始化(不能省略数组长度):\n");
printf("动态数组部分元素初始化:\n");
for(i=0;i<5;i++)
printf("%d ",c1[i]);
printf("\n\n");
printf("静态数组部分元素初始化:\n");
for(i=0;i<5;i++)
printf("%d ",c2[i]);
printf("\n※※※※※※※※※※※※※※※※※※※※※※※※※※※※\n\n\n");
printf("3.3:利用字符常量初始化:\n");
for(i=0;i<5;i++)
printf("%d ",d1[i]);
printf("\n数组大小=%d\n",sizeof(d1));
printf("\n※※※※※※※※※※※※※※※※※※※※※※※※※※※※\n\n\n");
printf("3.4:全部初始化为0:\n");
for(i=0;i<5;i++)
printf("%d ",d2[i]);
printf("\n数组大小=%d\n",sizeof(d2));
printf("\n※※※※※※※※※※※※※※※※※※※※※※※※※※※※\n\n\n");
printf("%#x\t%#x\t%#x\n%#x\t%#x\t%#x\n",a1,a2,b1,b2,c1,c2);
数组名可以看做是一个指针,指向的是数组的第一个元素的首地址,这个指针是不可以改变的,可以根据数组名访问不同的数组元素,如下所示
int b1[5]={1,2,3,4,5};
for(i=0;i<5;i++)
printf("%d ",*(b1+i));
只读数组和指定初始化器
#include<stdio.h>
#define MONTHS 12
void playArrays(int a[],int n);
int main()
{
//只读数组,程序只能从数组中检索值,不能把新值写入数组
const int a[MONTHS]={31,28,31,30,31,30,31,31,30,31,30,31};
int a1=3,b=0;
playArrays(a,MONTHS);
putchar('\n');
//a[1]++;
printf("%d\n",a[1]);
//指定初始化器(C99):在初始化列表中使用带方括号的下标指明待初始化元素
int arr[6]={[5]=212}; //把arr[5]初始化为212
playArrays(arr,6);
putchar('\n');
int days[MONTHS]={31,28,[4]=31,30,31,[1]=29};
/*
[4] =31,如果指定初始化器后面有更多的值,那么后面的值,一次初始化指定元素后面的元素
,即[5]会被初始化为30,[6]会被初始化为31
*/
playArrays(days,MONTHS);
putchar('\n');
return 0;
}
void playArrays(int a[],int n)
{
for(int i=0;i<n;i++)
{
printf("%d\t",a[i]);
if((i+1)%5==0)
printf("\n");
}
putchar('\n');
}
二维数组
定义:类型名 数组名[行长度][列长度];
引用:数组名[行下标][列下标](行下标的取值范围为[0,行下标-1][0,列下标-1])
术语 | 含义 | 下标规律 |
主对角线 | 从矩阵的左上角至右下角的连线 | i==j |
副对角线 | 从矩阵的右上角至左下角的连线 | i+j==N-1 |
上三角 | 主对角线以上的部分 | i<=j |
下三角 | 主对角线以下的部分 | i>=j |
初始化
- 顺序赋初值:类型名 数组名[行长度][列长度]={初值表}(根据数组元素在内存中的存放顺序,依次把初值表中的数据赋给元素)
/*3.1.1全部赋初值(此时可以省略行长度)*/
int b1[3][3]={1,2,3,4,5,6,7,8,9};
static int b2[][3]={1,2,3,4,5,6,7,8,9};
/*3.2.2部分赋初值*/
int b3[3][3]={1,2,3,4};
static b4[3][3]={1,2,3,4};
- 分行赋值:类型名 数组名[行长度][列长度]={{初值表0},{初值表1},……,{初值表k}}(k表示第几行);
列出了全部行,就可以省略行长度
/*3.2.1全部赋初值*/
int c1[3][3]={{1,2,3},{4,5,6},{7,8,9}};
static int c2[][3]={{1,2,3},{4,5,6},{7,8,9}};
/*3.2.2部分赋初值*/
auto int c3[3][3]={{1,2,3},{4},{7,8}};
static int c4[][3]={{1,2,3},{4},{7,8}};
printf("未初始化的二维数组\n");
printf("动态数组\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",a1[i][j]);
printf("\n");
}
printf("数组大小=%d\n",sizeof(a1));
printf("静态数组\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",a2[i][j]);
printf("\n");
}
printf("数组大小=%d\n",sizeof(a2));
printf("※※※※※※※※※※※※※※※※※※※※※※※※※※\n\n\n");
printf("3.1:顺序赋初值\n");
printf("3.1.1:对所有元素赋初值(静态数组和动态数组输出结果一致)\n");
printf("动态二维数组\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",b1[i][j]);
printf("\n");
}
printf("数组大小=%d\n",sizeof(b1));
printf("静态省略行长度二维数组\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",b2[i][j]);
printf("\n");
}
printf("数组大小=%d\n",sizeof(b2));
printf("\n");
printf("3.2.2:对部分元素赋初值");
printf("动态数组\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",b3[i][j]);
printf("\n");
}
printf("数组大小=%d\n",sizeof(b3));
printf("静态数组\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",b4[i][j]);
printf("\n");
}
printf("数组大小=%d\n",sizeof(b4));
printf("※※※※※※※※※※※※※※※※※※※※※※※※※※\n\n\n");
printf("3.2:分行赋初值\n");
printf("3.2.1:对所有元素赋初值(静态数组和动态数组输出结果一致)\n");
printf("动态二维数组\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",c1[i][j]);
printf("\n");
}
printf("数组大小=%d\n",sizeof(c1));
printf("静态省略行长度二维数组\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",c2[i][j]);
printf("\n");
}
printf("数组大小=%d\n",sizeof(c2));
printf("\n");
printf("3.2.2:对部分元素赋初值\n");
printf("动态二维数组\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",c3[i][j]);
printf("\n");
}
printf("数组大小=%d\n",sizeof(c3));
printf("省略行长度的静态二维数组\n");
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
printf("%d ",c4[i][j]);
printf("\n");
}
printf("数组大小=%d\n",sizeof(c4));
printf("※※※※※※※※※※※※※※※※※※※※※※※※※※\n\n\n");
字符数组与字符串
字符串常量:就是用一对双引号括起来的字符序列,即一串字符,它有一个结束符标志'\0'
例如:字符串“Happy”由6个字符组成,分别是'H','a','p','p','y','\0'。其中前五个是字符串的有效字符,'\0'是字符串结束符。
※字符串的有效长度:有效字符的个数,例如“Happy”的有效长度是5。
C语言将字符串作为特殊的一维字符数组处理(将字符串存入字符数组时,由于它有一个结束符'\0',数组长度至少是字符串的有效长度+1;
如果数组长度大于字符串有效长度+1,则除了存入的字符串,还有其他内容;
注:数组中第一个‘\0’前面的所有字符和第一个‘\0’一起构成字符串,也就是说,第一个‘\0’之后的其他数组元素与该字符串无关)
#include<stdio.h>
int main()
{
int i,number=0;
char str[20];
char s1[6];
static char s2[6];
/*1、字符串可以存放在一维字符数组中,例*/
char s3[6]={'H','a','p','p','y','\0'};
/*2、字符数组的初始化还可以使用字符串常量*/
char s4[6]={"Happy"};
//或
char s5[6]="Happy";
char s6[20]={'H','e','l','l','o','!','\0','w','o','r','d'};
printf("未初始化的动态字符数组\n");
printf("数组大小=%d\n",sizeof(s1));
printf("\"%s\"\n\n",s1);
printf("未初始化的静态字符数组\n");
printf("数组大小=%d\n",sizeof(s2));
printf("\"%s\"\n\n",s2);
printf("数组大小=%d\n",sizeof(s3));
printf("%s\n",s3);
printf("数组大小=%d\n",sizeof(s4));
printf("%s\n",s4);
printf("数组大小=%d\n",sizeof(s5));
printf("%s\n",s5);
printf("数组大小=%d\n",sizeof(s6));
printf("%s\n",s6);
printf("\n\n――――――――――――――――――――――――――――――\n");
printf("使用字符串编程:(输入一个以回车键为结束标志的字符串提取数字字符)\n");
printf("请输入一个字符串:");
i=0;
while((str[i]=getchar())!='\n')
i++;
str[i]='\0'; //将结束符'\0'存入数组
for(i=0;str[i]!='\0';i++)
if(str[i]>='0'&&str[i]<='9')
number=number*10+(str[i]-'0');
printf("%d\n",number);
return 0;
}
数组元素作为函数参数
#include<stdio.h>
void Showmember(int number);
int main()
{
int i,a[10];
for(i=0;i<10;i++)
a[i]=i;
for(i=0;i<10;i++)
Showmember(a[i]);
return 0;
}
void Showmember(int number)
{
printf("Show the member is %d\n",number);
}
数组作为函数参数
#include<stdio.h>
#define CLS 2
#define ROW 2
//这三种形式等价
//int sum_2(int (*)[CLS],int);
//int sum_2(int [][CLS],int);
//int sum_2(int a[][CLS],int n);
//这三种形式等价
//int sum_3(int [][CLS][ROW],int);
//int sum_3(int (*)[CLS][ROW],int);
int sum_3(int a[][CLS][ROW],int n);
int main()
{
int a[4][CLS]={
{1,2},
{3,4},
{5,6},
{7,8}
};
for(int i=0;i<4;i++)
{
for(int j=0;j<CLS;j++)
{
printf("%d|",a[i][j]);
printf("%d|",*(a[i]+j));
printf("%d\t",*(*(a+i)+j));
}
printf("\n");
}
for(int i=0;i<4;i++)
{
for(int j=0;j<CLS;j++)
{
printf("%#p|",&a[i][j]);
printf("%#p|",a[i]+j);
printf("%#p\t",*(a+i)+j);
}
printf("\n");
}
printf("sum=%d\n",sum_2(a,4));
int (*p)[CLS]=a; //数组指针
for(int i=0;i<4;i++)
{
for(int j=0;j<CLS;j++)
{
printf("%d|",p[i][j]);
printf("%d|",*(p[i]+j));
printf("%d\t",*(*(p+i)+j));
}
printf("\n");
}
for(int i=0;i<4;i++)
{
for(int j=0;j<CLS;j++)
{
printf("%#p|",*(p+i)+j);
printf("%#p|",p[i]+j);
printf("%#p\t",&p[i][j]);
}
printf("\n");
}
printf("sum=%d\n",sum_2(p,4));
int b[2][CLS][ROW]={
{
{1,2},
{3,4}
},
{
{5,6},
{7,8}
}
};
for(int i=0;i<2;i++)
{
printf("{\n");
for(int j=0;j<CLS;j++)
{
printf("\t");
for(int k=0;k<ROW;k++)
{
printf("%d|",b[i][j][k]);
printf("%d|",*(*(*(b+i)+j)+k));
printf("%d|",*(*(b[i]+j)+k));
printf("%d\t",*(b[i][j]+k));
}
printf("\n");
}
printf("}\n");
}
printf("sum=%d\n",sum_3(b,2));
int (*p2)[CLS][ROW]=b;
for(int i=0;i<2;i++)
{
printf("{\n");
for(int j=0;j<CLS;j++)
{
printf("\t");
for(int k=0;k<ROW;k++)
{
printf("%#p|",*(*(p2+i)+j)+k);//*(*(b+i)+j)+k
printf("%#p|",*(p2[i]+j)+k);
printf("%#p|",p2[i][j]+k);
printf("%#p\t",&p2[i][j][k]);
}
printf("\n");
}
printf("}\n");
}
printf("sum=%d\n",sum_3(p2,2));
}
int sum_2(int a[][CLS],int n)
{
int sum=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<CLS;j++)
{
sum+=a[i][j];
}
}
return sum;
}
int sum_3(int a[][CLS][ROW],int n)
{
int sum=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<CLS;j++)
{
for(int k=0;k<ROW;k++)
{
sum+=a[i][j][k];
}
}
}
return sum;
}