【从浅入深,全面掌握数组的操作与优化技巧】

5c909bbc17774ebc8e5cddf55ccaa19c.png

#include<stdio.h>
#define N 10
int main()
{
    int a[N] = { 0 }; //定义并初始化数组
    return 0;
}

 概念:数组是具有相同数据类型的集合。

 

数组的内存布局

#include<stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int c = 30;
	printf("%p\n", &a);
	printf("%p\n", &b);
	printf("%p\n", &c);
	return 0;
}

a0b0ed5d64794fb7b217cae03139a6ed.png

我们来看一下运行的结果 

84a40cd8130d4fa1bb29fbddddc98c43.png

  • 我们发现,先定义的变量,地址是比较大的,后续依次减小。
  • 这是为什么呢?
  • a,b,c都在main函数中定义,也就是在栈上开辟的临时变量。而a先定义意味着,a先开辟空间,那么a就先入栈,所以a 的地址最高,其他类似。

c1d7186215e045afafccc84af00b7586.png

 665bd4ffa6a6461e9be4b109abf64ced.gif

#include<stdio.h>
#define N 10
int main()
{
	int a[N] = { 0 };
	for (int i = 0; i < N; i++) {
		printf("&a[%d]: %p\n", i, &a[i]);
	}
	return 0;
}

3bad4aa2ea8d478fb1cef4699ce43d5b.png

  • 我们发现,数组的地址排布是:&a[0] < &a[1] < &a[2] < ... < &a[9]。
  • 该数组在main函数中定义,那么也同样在栈上开辟空间
  • 数组有多个元素,那么肯定是a[0]先被开辟空间啊,那么肯定&a[0]地址最大啊,可是事实上并非如此!
  • 数组是整体申请空间的,然后将地址最低的空间,作为a[0]元素,依次类推!所以我们不能把数组认为是一个个独立的元素,它们是整体被开辟,整体被释放。

646cbc158137413692b24cadb975e1b8.png

 ea44acf9babc45219e1fed53f25cea44.jpeg

理解&a[0]和&a的区别

  • &a[0]取的是首元素的地址。
  • &a取的是整个数组的地址。
#include<stdio.h>
int main()
{
	char* c = NULL;
	short* s = NULL;
	int* i = NULL;
	double* d = NULL;

	printf("%d\n", c);
	printf("%d\n\n", c + 1);

	printf("%d\n", s);
	printf("%d\n\n", s + 1);

	printf("%d\n", i);
	printf("%d\n\n", i + 1);

	printf("%d\n", d);
	printf("%d\n\n", d + 1);
	return 0;
}

566898df5bbb4eeeb8ff0e9955981798.png

结论:对指针+1,本质加上其所指向类型的大小。

3131885228e544b788dcd4801ff54513.jpeg

 如果发生类型转化呢?

4d0f596eb4f9496ea12ad30dadaf23d4.png

9307cc9acbfd455f9d7e9ed8ddf0fe6c.png

 

 结论:

  • 如果发生强制类型转换,对指针+1,本质加上其所指向强制类型转换的大小。
  • 二级指针以以上所有的指针+1,在32位平台上,都是跳过4个字节。

 

ca0584caa00542209b5fa039962ef493.png

#include<stdio.h>
int main()
{
	char arr[10] = { 0 };

	printf("%p\n", &arr[0]); //首元素的地址
	printf("%p\n", &arr[0] + 1); //第二个元素的地址

	printf("%p\n", &arr); //数组的地址
	printf("%p\n", &arr + 1); //下一个数组的地址
	return 0;
}

278be54110b94099956da4bfbb46e65c.png

 

数组名使用的时候,只有两种情况代表整个数组

  1. &arr:数组的地址
  2. sizeof(arr):单独使用数组名

&arr[0] 和 &arr虽然地址数字一样大,但是类型意义完全不同。

be24bd36381f44a092f13233db41e94b.png

为什么地址数字是一样大的呢???

        因为首元素的地址和数组的地址,在地址对应的字节是重叠的,所以地址的数据值相等。

        地址对应的字节都是变量开辟的空间中众多字节当中,地址最小的那个。

 

数组名a做为左值和右值的区别

a3823d47eea949218b5dbecdfbbcf77e.png

4ed65f92da4b441ba9ec73130aef40a2.png

数组只能整体被初始化,不能整体赋值,如果想要赋值,只能逐个元素进行赋值。

例如:arr[0]  =  1; arr[1] = 2;

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值