嵌入式学习-c语言数组

数组概述

数组是构造数据类型之一,是具有一定顺序关系的若干个变量的集合。数组中各元素的数据类型要求相同,数组可以是一维的,也可以是多维的。

一维数组

注意:数组名是地址常量!!!注意是常量!!不能被修改!!

用代码进行测试:

#include<stdio.h>

int main(){
	int i;
	int a[6] = {1,2,3,4,5,6};
	printf("该数组内存空间为%d\n",sizeof(a));//输出为24
	printf("该数组的起始地址为%p\n",a);//应该注意到这里没有加取地址符,数组名本身就代表了地址
	for(i=0;i<=5;i++){
		printf("数组第%d个数为:%d\t",i+1,a[i]);
        printf("数组元素地址为:%p\n",&a[i]);//这里就要加取地址符,因为不是数组名
	}
	return 0;
}

输出结果为:

该数组内存空间为24
该数组的起始地址为0xbfd0cb98
数组第1个数为:1	数组元素地址为:0xbfd0cb98
数组第2个数为:2	数组元素地址为:0xbfd0cb9c
数组第3个数为:3	数组元素地址为:0xbfd0cba0
数组第4个数为:4	数组元素地址为:0xbfd0cba4
数组第5个数为:5	数组元素地址为:0xbfd0cba8
数组第6个数为:6	数组元素地址为:0xbfd0cbac

要注意到:数组名本身就是地址,在输出数组首地址时,直接用数组名即可,不用再加取地址符号了~但只要不是求首地址,而是其它元素的地址,那么一定要加取地址符号&

一维数组的初始化

初始化方式:在定义数组时,为数组元素赋初值
int a[5] = {1,2,3,4,5};
说明:
1、数组不初始化,其元素值为随机数
2、对static数组元素不赋初值,系统会自动赋以0值
3、只给部分数组元素赋初值,那么剩余的元素会自动赋0值

注意事项

1、C语言对数组不作越界检查,使用时要注意:
int a[5]; a[5]=10; 这段代码并不会报错
2、关于用变量进行数组维数定义:
int i = 5; int a[i];
3、数组只能通过元素来访问,不能一次引用整个数组
在这里插入图片描述

如何求数组元素个数?

假设数组元素个数为n,即数组维数为n,那么
n = sizeof(数组名) / sizeof(数组类型)
因为 ↑是总内存,总长度 ↑是单个元素内存,单个长度

二维数组

例如 int a[3][4],float b[2][5]都是二维数组。

存放顺序:由于内存是一维的,但是仍要把二维数组放到一维的内存当中,这个时候只要按行序优先的原则存储即可。

比如:
int a[3][2]
在这里插入图片描述

0  a[0][0]
1  a[0][1]
2  a[1][0]
3  a[1][1]
4  a[2][0]
5  a[2][1]

深入理解:

由于二维数组就是一行一行存储的,所以完全可以把int a[3][2]的二维数组看成是三个一维数组:

三种赋初值实例:

#include<stdio.h>

int main(){
	//三种方式给数组赋初值
	int a[3][2] = {{1,2},{5,6},{9,10}};

	int b[3][2];
	int c[3][3];
	int i,j;
	int value = 1;
	for(i=0;i<3;i++){
		for(j=0;j<2;j++){
			b[i][j] = 1;
		}
	}

    for(i=0;i<3;i++){
		for(j=0;j<3;j++){
			c[i][j] = value++;
		}
	}

	printf("数组a为:\n");
	for(i=0;i<3;i++){
		for(j=0;j<2;j++){
			printf("%d ",a[i][j]);
		}
	}

	printf("\n数组b为:\n");
	for(i=0;i<3;i++){
		for(j=0;j<2;j++){
			printf("%d ",b[i][j]);
		}
	}

	printf("\n数组c为 :\n");
	for(i=0;i<3;i++){
		for(j=0;j<3;j++){
			printf("%d ",c[i][j]);
		}
	}
	return 0;
}

输出结果为:

数组a为:
1 2 5 6 9 10 
数组b为:
1 1 1 1 1 1 
数组c为 :
1 2 3 4 5 6 7 8 9

当然了,在赋初始值的时候完全可以缺省一些数据
比如:
在这里插入图片描述
在这里插入图片描述
但是,二维数组在定义时只能缺省行值,不能缺省列值
例如,使用C语言定义一个二维数组可以这样写:

int array[][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

这里省略了行数,因为编译器可以根据初始化的值自动推断出数组的行数为3。

然而,二维数组的列数在定义时必须明确指定。这是因为在内存中,二维数组的每一行是连续存储的,而列数确定了每一行的存储长度,所以在定义时必须指定列数,编译器才能正确分配内存空间。

因此,省略列数是不可以的,因为编译器无法确定每一行的长度。你可以理解为省略列数会导致数组的行长度无法确定,从而导致内存分配问题。

如果在定义时只用一个花括号呢?即int a[2][2] = {1,2}这种,那么就会从上到下,从左到右依次填充,剩下的补0。如图所示。
在这里插入图片描述

测试二维数组内存地址连续性

printf("\n数组a的元素地址分别为:");
	for(i=0;i<3;i++){
		for(j=0;j<2;j++){
        	printf("%p\t",&a[i][j]);
		}
		printf("\n");
	}

	printf("\n数组c的元素地址分别为:");
	for(i=0;i<3;i++){
		for(j=0;j<3;j++){
        	printf("%p\t",&c[i][j]);
		}
		printf("\n");
	}

输出结果为:

数组a的元素地址分别为:0xbfd949ac	0xbfd949b0	
0xbfd949b4	0xbfd949b8	
0xbfd949bc	0xbfd949c0	

数组c的元素地址分别为:0xbfd949dc	0xbfd949e0	0xbfd949e4	
0xbfd949e8	0xbfd949ec	0xbfd949f0	
0xbfd949f4	0xbfd949f8	0xbfd949fc	

我们可以发现数组元素地址确实是一维连续

测试二维数组名的作用以及是否可以拆分为一维数组

printf("输出a的地址:%p\n",&a);
printf("输出a[0]的地址:%p\n",&a[0]);
printf("输出a[1]的地址:%p\n",&a[1]);
printf("输出a[2]的地址:%p\n",&a[2]);

输出结果:

输出a的地址:0xbfbe55ac
输出a[0]的地址:0xbfbe55ac
输出a[1]的地址:0xbfbe55b4
输出a[2]的地址:0xbfbe55bc

对照上面a数组的地址:

数组a的元素地址分别为:0xbfbe55ac	0xbfbe55b0	
0xbfbe55b4	0xbfbe55b8	
0xbfbe55bc	0xbfbe55c0	

我们可以发现二维数组名依然表示数组的起始地址,而且可以拆分为一维数组使用

测试二维数组所占内存空间

这里以int a[3][2]为例:

printf("数组a占用的内存总空间为:%d\n",sizeof(a));
printf("a[0]占用的内存空间为:%d\n",sizeof(a[0]));

输出结果为:

数组a占用的内存总空间为:24
a[0]占用的内存空间为:8

说明二维数组看作一维数组的数组名确实是可以当作正常数组名来用的,后续可能会以这个为基础来使用指针操作数组

多维数组

具有两个或两个以上下标的数组是多维数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值