当前位置 : 主页 > 编程语言 > c语言 >

五、数组

来源:互联网 收集:自由互联 发布时间:2023-08-28
0. 一个问题 int a,b;如果我们要定义100个整型变量呢?int a0,a1,a2,a3,...,a99; 很显然上面的这种定义多个变量的方法,不科学, 不人道. 有没有办法可以一次定义一组相同类型的变量呢? 数组 1 什

0. 一个问题

int a,b;

如果我们要定义100个整型变量呢?
int a0,a1,a2,a3,...,a99;

很显然上面的这种定义多个变量的方法,不科学, 不人道.

有没有办法可以一次定义一组相同类型的变量呢?

数组

1 什么是数组?

数组是一组具有相同数据类型的有序集合.

"有很多个数据" "相同的数据类型" "有序集合"

在C语言中数组有 :

一维数组

二维数组

三维数组

四维数组

.....

但是 , 有人(游铭)说 : "C语言中只有一维数组"

2 一维数组

2.1 一维数组定义格式

元素的类型 数组名[元素个数] {= {初始值列表}};

"元素类型" :

指定数组中元素的类型, 而不是数组的类型!!!

可以是C语言中, 任意合法的类型(基本类型,构造类型,指针类型)

"数组名" :

一个数组的名字 , "标识符"

"元素个数"

整型表达式(一般为常量),指定数组中元素的个数.

C语言中规定定义数组时,需要指定(隐含指定 : 可以由编译器推断出)数组元素的个数.

为什么要指定个数呢? 定义数组时, 就需要分配空间给数组.

例子 :

int a[10];//定义了一个数组, 名为a ,里面有10个int类型的元素
		//a 是一个有 10个int类型元素的  数组
		typeof(a) : int[10]
         
int a[4] = {1,2,3,4};
	//定义了一个数组,名为a,里面有4个int类型的元素.
	//而且这4个元素的初始值分别为 : 1,2,3,4
	typeof(a) : int[4]
     
int a[100];

2.2 数组元素的引用

语法 :

数组名[下标];

在C语言中数组的==下标是从 0 开始== , 0 ,1,2,3,4,5,...,n-1

例子 :

int a[10];//这里面有10个int类型的元素
	分别是 :
		a[0]
a[1]
a[2]
...
a[9]
//a[10] 特别强调 没有a[10] 这个元素,数组越界.
   
typeof(a[0]) : int
typeof(a[1]) : int
typeof(a[2]) : int
...
typeof(a[9]) : int
   
a[0] a[1] a[2] ... a[9] 就是一个普通的int类型的变量!!!
   
int a[10];
int b;

引用数组元素 和 引用普通变量是一样的,数组元素也有左值,也有右值.

a[0] = 100;//a[0] 代表 数组元素a[0] 的地址("a[0]的左值")
x = a[0];//a[0] 代表数组元素 a[0] 的值("a[0]的右值")
scanf("%d",&b);
scanf("%d",&a[0]);

//scanf("%d",&a);//"一次性输入整个数组" ,可以吗?
	不可以的, error

2.3 一维数组在内存中存放

在 C 语言中, 用一组地址连续的存储空间, 从低地址到高地址依次存放数组中的每个元素.

先存放a[0] , a[0] 这个元素的后面是 a[1] ,a[1] 后面是a[2] ...

例子 : 假设 int 占 32bits(4bytes)

int a[10];
		//运行时,系统会为数组a分配 10*sizeof(int) = 40 bytes
	a[0]		a[1]	 a[2]       a[3]
|----------|----------|---------|---------|...
0x3000     0x3004     0x3008     0x300c   ...

&a[0] == 0x3000
&a[1] == 0x3004
&a[2] == 0x3008
...

练习 :

循环输出 int a[10]中每个元素的额地址

printf("%p\n",&a[0]);//%p 把后面的那个值,当做一个地址,unsigned, 十六进制输出

for(int i = 0;i < 10;i++)
{
printf("%p\n",&a[i]);
}

2.4 初始化数组

数组的初始化用 { }

初始化 : 是指定义他的时候, 就给他值, 就是初始化.

(1) 给每一个元素初始化

如 :

int a[10] = {1,2,3,4,5,6,7,8,9,10};
		//初始化 : 定义数组对象时,就给他值

int b[10];
b = {1,2,3,4,5,6,7,8,9,10};//error

//定义完数组,后面就只能给元素一个一个赋值,就不能对数组整体赋值啦.
b[0] = 1;
b[1] = 2;
...

(2) 可以只对部分元素初始化,后面的元素自动初始化为 0

如 :

int a[5] = {1,2};//只初始化了前面两个元素
==>
a[0] = 1;
	a[1] = 2;
	a[2] = 0;
	a[3] = 0;
	a[4] = 0;

(3) 如果对全部元素都赋初值,在定义数组时,可以不指定"元素个数"

why? 因为编译器这个时候, 很聪明, 他可以推断出你数组的元素个数.

int a[] = {1,2,3,4,5,6,7,8,9,10};
	//编译器推断  数组a中有 10个元素

练习 :

(1) 定义一个一维数组,并通过键盘一一对每个元素进行赋值,并且输出.

int a[10];

scanf("%d",&a[0]);
scanf("%d",&a[1]);
scanf("%d",&a[2]);
...
    
==>
    int i;
	for(i = 0;i < 10;i++)
    {
        scanf("%d",&a[i]);
    }

	for(i = 0;i < 10;i++)
    {
        printf("a[%d] = %d\n",i,a[i]);
    }

(2) 遍历数组 : 访问数组中的每一个元素一次仅一次.

求一个int类型数组中的最大值,最小值,以及所有元素的和.

int a[10];

int max;//保存数组a中的最大值
int min;//保存数组a中的最小值
int sum;

max = a[0];//假设 a[0]最大

int i;


if a[1] > max
max = a[1]

if a[2] > max
max = a[2]

if a[3] > max
max = a[3]

if a[4] > max
max = a[4]
....
printf("max = %d\n",max);

==> 
if(a[i] > max)
{
  max = a[i];
}
	i++;

for()
{
if(a[i] > max)
{
  max = a[i];
}
	i++;
}

#include <stdio.h>

int main()
{
  int a[10];
  int max;//保存数组a中的最大值
  int min;//保存数组a中的最小值
  int sum;//保存数组的和

  int i;
  //从键盘上输入数组元素的值
  for(i = 0;i < 10;i++)
  {
      scanf("%d",&a[i]);
  }

  max = a[0];//假设a[0] 最大
  for(i = 1;i < 10;i++)
  {
      if( a[i] > max )
      {
          max = a[i];
      }
  }

  min = a[0];//假设a[0] 最小值
  for(i = 1;i < 10;i++)
  {
      if(a[i] < min)
      {
          min = a[i];
      }
  }

  sum = 0;
  for(i = 0;i < 10;i++)
  {
      sum = sum + a[i];
  }

  printf("max = %d\n",max);
  printf("min = %d\n",min);
  pintf("sum = %d\n",sum);

  return 0;
}


3 二维数组

0 回顾下一维数组

定义格式 :

元素的类型 数组名[元素个数];

int a[4];//定义了一个数组 ,名为a,里面含有4个int类型的元素
		//a是一个含有4个int类型元素的数组

		//上面的这条语句,不仅定义了一个数组a,同时还声明了一个新的类型
		//"像 a 这样的类型"
		//typeof(a) : int[4]

	定义一个里面包含  3个a这样的类型的数组,该如何定义呢?
     typeof(a) b[3];
	==>
     int[4] b[3]
 ==>
     int b[3][4];//二维数组

1 二维数组"矩阵"

由上面的推导的过程可以提出 :

​ C语言中,二维数组实际就是一个一维数组,只不过这个一维数组中的每一个元素又是一个数组.

int b[3][4];//int[4] b[3];
数组b中,含有3个元素
 b[0] -> b[0] 里面又包含4 int
 b[1] -> b[1] 里面又包含4 int
 b[2] -> b[2] 里面又包含4 int
 
"矩阵" : 把b看做一个 3行4列 的矩阵

2 二位数组的定义

类型说明符 数组名[行数][列数];//从"矩阵"角度来看二维数组

"类型说明符" : 二维数组中元素的类型, C语言中任意合法的类型都可以

"行数" "列数" : 常量 或者 常量表达式

例子 :

int a[3][4];//里面有 3*4 int  int[4] a[3]

(3) 二维数组元素的引用

数组元素的引用 :
	数组名[下标]
     
int a[3][4];//int[4] a[3]

a[0] ___ ___ ___ ___ //这一行,又是一个数组,数组名为a[0]
a[1] ___ _x_ ___ ___ //这一行,又是一个数组,数组名为a[1]
a[2] ___ ___ ___ ___ //这一行,又是一个数组,数组名为a[2]
 
 引用元素x , x是数组a[1] 中的第1个元素,数组名[1] ==> a[1][1]
 并且引用二维数组中元素和引用普通变量是一样的,也有左值,也有右值.
 	a[1][1] = 150;//a[1][1]是左值,a[1][1]的地址
		
		int b = a[1][1];//a[1][1] 是右值,a[1][1]的值

(4)二维数组的存放

按行存放,即先顺序存放第一行元素,然后再存放第二行的元素,.....

image-20230705145855457

why? ??

​ 因为二维数组就是一维数组

int a[3][4];//int[4] a[3]
	   a[0]          a[1]           a[2]
|---------------|--------------|------------|
a[0][0]-a[0][3] a[1][0]-a[1][3] a[2][0]-a[2][3]

#include <stdio.h>

int main()
{
 int a[3][4];
 printf("a[0][3] = %p\n",&a[0][3]);
 printf("a[1][0] = %p\n",&a[1][0]);
     
 return 0;
}
  

(5) 二维数组的初始化

二位数组的初始化是指 定义二位数组时,就赋初值.

数组的初始化 用 {}

可以指定每个元素的值,也可以只指定部分元素的值.

<1> 分行给二维数组赋初始值
int a[3][4] = {
 {1,2,3,4},//a[0]
 {5,6,7,8},//a[1]
 {9,10,11,12}//a[2]
};

<2> 将所有的元素写在一个{}内,按数组元素的顺序一次对各元素初始化.

int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};

<3> 对部分元素赋初始值,其余元素自动置 0
int a[3][4] = {
 {1,2},//a[0] ==> {1,2,0,0}
 {3},  //a[1] ==> {3,0,0,0}
 {5}   //a[2] ==> {5,0,0,0}
};

<4> 如果对全部元素都赋初值,定义时元素个数可以省略(第一维),第二维不能省略.
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};

练习 :

1.定义一个二维数组,从键盘上按行输入每一个元素的值,再输出.

int a[3][4];

//i表示行数
for(i = 0; i < 3;i++)
{
    //j表示列数
    for(j = 0 ; j < 4 ;j++)
    {
        scanf("%d",&a[i][j]);
    }
}

//再按行打印每一个元素,每行后面输出一个 \n
for(i = 0; i < 3;i++)
{
    //j表示列数
    for(j = 0 ; j < 4 ;j++)
    {
        printf("%d ",a[i][j]);
    }
    printf("\n");
}

【文章原创作者:站群服务器 http://www.558idc.com/mggfzq.html 欢迎留下您的宝贵建议】
上一篇:java项目实训笔记:前端框架复习
下一篇:没有了
网友评论