C语言学习笔记(6)数组

系列文章目录

C语言学习笔记(1)常量和变量
C语言学习笔记(2)条件判断 if语句
C语言学习笔记(3)循环
C语言学习笔记(4)逻辑运算
C语言学习笔记(5) 嵌套和分支



前言

  • 数据可以存放在变量里,每一个变量有一个名字,有一个类型,还有它的生存空间。
  • 如果我们需要保存一些相同类型、相似含义、相同生存空间的数据,我们可以用数组来保存这些数据,而不是用很多个独立的变量。
  • 数组是长度固定的数据结构,用来存放指定的类型的数据。
  • 一个数组里可以有很多个数据,所有的数据的类型都是相同的

为什么要使用数组:

  1. 解决了大量同类型数据的存储和使用问题(如果不使用数组,就需要声名大量的变量),数组中的每个元素就是一个变量。
  2. 数组可以模拟现实世界(一维数组,二维数组,多维数组。。。)

我们通常不直接使用数组(缺:长度不可变,操作困难),可以使用已经设计好的数组(同时还设计了对数组的操作)。所以,数组不是我们学习的重点。

是否存在多维数组:
不存在。

  • 因为内存是线性一维的
  • n 维数组可以看作每个元素是 (n-1) 维数组的一维数组
    例如: int a[3][4]:该数组是含有3个元素的一维数组,只不过每个元素可以再分成4个小元素。
    int a[3][4][5]:该数组也是含有3个元素的一维数组,只不过每个元素都是[4][5](4行5列)的二维数组。

一、问题引入

输入:用户输入一串数字
输出:这串数字的平均值,这串数字中大于平均值的数

这时通过为每个数定义一个变量不现实。

# include<stdio.h>
int main()
{
	int number[100]; //声明一个数组,数组长度为100,数据都是int
	double sum = 0;//这些数的和
	int cnt = 0;//计算一共输入多少个数
	int x; // 在输入数字的过程中,存储每个数字
	
	scanf("%d",&x);
	while(x != -1){
		number[cnt] = x; //对数组中的元素进行赋值
		sum += x;
		cnt ++;
		scanf("%d",&x);
	} // 在 number 中存储数字
	
	if (cnt > 0){
		printf("平均值:%f\n",sum/cnt);
		int i;
		for(i=0;i<cnt;i++){
			if(number[i] > sum/cnt){
				printf("大于平均值的数字:%d \n",number[i]);// 使用数组中的元素
			}
		}
	} 
	return 0;
}

注:数组的索引序号从0开始

二、数组的定义

语法格式:
<类型> 变量名称 [元素数量]

三、数组特点

  • 是一种容器
  • 元素数量必须是整数,且固定不可改变
  • 元素类型必须相同,占用存储空间大小相等
  • 一旦被创建,不能改变大小
  • 数组中的元素在内存中是连续依次排列的

举例:

int a[10]
  1. 是一个 Int 的数组
  2. 有10个单元。a[0],a[1],…,a[9]
  3. 每个单元是一个 int 的数据类型
  4. 每个单元可以出现在赋值的左边或者右边
  5. 出现在左边是赋值
  6. 出现在右边是索引
  7. 索引可以是变量,也可以是常量

下标范围: 编译器和运行环境都不会检查数组下标是否越界,无论是对数组单元做读还是做写。
程序员需要自己维护索引在正确范围内。

四、数组的初始化

1.无具体大小

数组的集成初始化,给出一组数来初始化。

int a[] = {2,4,6,7,1,3,5,9,11,13,23,14,32};
  • 没有给出数组的具体大小,而是让编译器自己去数
  • 直接用 大括号 { } 给出数组的所有元素的初值

2.有具体大小

如果给出了数组的具体大小,但是赋值没有那么多。

//一维数组
int a[13] = {5};

//二维数组
int a[3][2] = {1, 2, 3, 4, 5, 6}   // 第一种赋值方法

int b[3][2] = {
	{1, 2},
	{3, 4},
	{5, 6}
};  // 第二种赋值方法

这个时候,赋值的单位为5,其余为0。

3.定位初始化

int a[10] = {[0]=2,[2]=3,6};
  • 用 [n] 在初始化数据中给出定位
  • 没有定位的数据接在前面的位置后面
  • 其他位置补零
  • 也可以不给出数组的大小,让编译器算
  • 特别适合初始化数据稀疏的数组

4. 不初始化

int a[5];

数组所有元素是垃圾值

5. 清零

int a[5] = {0};

数组所有元素都是0

错误写法

int a[5];
a[5] = {1, 2, 3, 4,  5};

错误原因:

  • a[5] = {1, 2, 3, 4, 5} 的意思是为 数组a 的第6个元素赋值。
  • 数组a 只有5个元素
  • {1, 2, 3, 4, 5} 不能直接赋给 数组a 其中的某个元素
  • 只有在定义数组的同时,才可以整体赋值(这时 a[5] 表示数组的长度是5)
int a[5] = {1, 2, 3, 4,  5};
int b[5];

如果要把 数组a 的值赋值给 数组b

错误写法:

b  = a;

正确写法:使用循环

for (int i=0; i < 5; i++)
	b[i] = a[i];

错误原因:

  • a 表示数组名,数组名的含义时数组第一个元素的地址。
  • b = a 相当于时把 a 的值赋值给 b。

五、数组的大小

sizeof 运算符给出整个数组所占的内容的大小,单位是字节。

首先初始化数组 a

int a[10] = {[0]=2,[2]=3,6};

然后计算数组的大小(单位:字节)

printf("%d\n",sizeof(a));
输出:40

这个是整个数组的大小。那么,一个单位的大小(单位:字节)

printf("%d",sizeof(a[0]));
输出:4

这样的话,40 / 4 = 10,一共有 10 个单元。

也可以直接计算出数组的大小

printf("%d",sizeof(a)/sizeof(a[0]));

计算数组的大小公式总结
sizeof(a) / sizeof(a[0])

  • sizeof(a[0])给出数组中单个元素的大小,于是相除就得到了数组的单元个数
  • 这样,即使修改数组中的初始数据,也不需要修改遍历的代码

六、 数组的赋值

不能直接拿一个数组变量赋给另外一个数组变量。

错误示例

int a[10] = {[0]=2,[2]=3,6};
int b[] = a; // × 不能这样赋值 
  • 数组变量本身不能被赋值
  • 要把一个数组的所有元素交给另一个数组,必须采用遍历,数组之间互相赋值的唯一方法。
	int a[10] = {[0]=2,[2]=3,6};
	int b[10];
// 赋值
	for(int i = 0; i < sizeof(a)/sizeof(a[0]);i++){
		b[i] = a[i];
	} 
// 查看 数组 b 中的元素
	for (int i = 0;i<10;i++){
		printf("%d\n",b[i]);
	}

七、数组的编程实例

1.搜索

// 搜索给定的元素是否在数组里面

# include<stdio.h>

int search(int key, int a[], int length)
/* 
找出 key 在数组 a 中的位置
@ param key  要寻找的数字
@ param a  要寻找的数组
@ param length  数组a的长度
@ return  如果找到,返回其在 a 中的位置;如果找不到则返回-1
*/ 
{
	int ret = -1;
	int i;
	for (i=0; i < length; i++){
		if (a[i] == key){
			ret = i;
			break;
		}
}
return ret;
}

int main(void)
{
	int a[] = {2,4,6,7,1,3,5,9,11,13,23,14,32};
	int x;
	int loc;
	printf("请输入一个数字:");
	scanf("%d",&x);
	loc = search(x,a,sizeof(a)/sizeof(a[0]));
	if(loc != -1){
		printf("%d在第%d个位置上\n",x,loc);
	}
	else {
		printf("%d不存在\n",x);
	} 
	
	return 0;
}
  • 数组作为函数参数时,必须再用另一个参数来传入数组的大小。

原因:

  1. 数组作为参数传入时,不能利用 sizeof来计算数组的元素个数(用指针解释)。
  2. 不能再 [ ] 中给出数组的大小。

四、二维数组

1. 定义

int a[3][5]; // 3行 5 列

2. 遍历

需要两个循环

for (i=0;i<3;i++){
	for (j=0;j<5;j++){
		a[i][j] = i * j;
	}
}

3. 二维数组的初始化

列数不可以省略;行数可以省略

int a[][5] = {
		{0,1,2,3,4},
		{2,3,4,5,6},
};
  • 列数必须是给出的,行数可以由编译器来数
  • 每行一个{ },逗号分隔
  • 最后的逗号可以存在
  • 如果省略,表示补零
  • 可以用定位(两个方括号[] [] )
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值