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

简介: 【从浅入深,全面掌握数组的操作与优化技巧】
#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;
}


我们来看一下运行的结果



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


#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;
}



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


理解&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;
}



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


如果发生类型转化呢?



结论:


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


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

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


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


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


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

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


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




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

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

相关文章
|
分布式计算 数据可视化 大数据
Hue--介绍、功能、架构 | 学习笔记
快速学习 Hue--介绍、功能、架构
2860 0
Hue--介绍、功能、架构 | 学习笔记
|
9月前
|
前端开发 测试技术 API
GraphQL 中的分页与排序:一分钟浅谈
本文深入介绍了 GraphQL 中的分页与排序功能,解释了为何这些功能在处理大量数据时至关重要,并详细说明了如何通过 `first` 和 `after` 参数实现分页,以及如何使用 `orderBy` 参数进行排序。同时,文章还探讨了常见问题及解决方法,帮助开发者避免陷阱,提升查询性能和用户体验。
213 70
|
11月前
|
存储 缓存 Docker
docker中挂载数据卷到容器
【10月更文挑战第16天】
291 3
|
存储 Python
GEE谷歌地球引擎计算每隔8天的遥感影像数据的平均值
【2月更文挑战第5天】本文介绍在谷歌地球引擎(Google Earth Engine,GEE)中,计算长时间序列遥感影像数据在多年中,在每一个指定天数的时间范围内的平均值的方法~
624 7
GEE谷歌地球引擎计算每隔8天的遥感影像数据的平均值
|
存储 SQL 分布式计算
当NameNode宕机时的应急响应与恢复策略
【8月更文挑战第31天】
406 0
|
存储 分布式计算 负载均衡
在Linux中,什么是集群,并且列出常见的集群技术。
在Linux中,什么是集群,并且列出常见的集群技术。
|
搜索推荐 安全 vr&ar
虚拟现实技术在远程教育中的沉浸式学习体验
虚拟现实技术在远程教育中的沉浸式学习体验
|
网络协议 网络虚拟化
遇到ARP欺骗攻击,咋整?别慌!这3招教制服它!
遇到ARP欺骗攻击,咋整?别慌!这3招教制服它!
1252 0
|
Ubuntu Linux 芯片
史上最全的LED点灯程序—使用STM32、FPGA、Linux点亮你的LED灯
不知道小伙伴们点亮过多少板子的LED灯,有很多小伙伴留言说讲一下stm32、fpga、liunx他们之间有什么不同,不同点很多,口说无凭,今天就来点亮一下stm32、fpga和liunx板子的led灯,大家大致看一下点灯流程和点灯环境以及点灯流程,就能大概的了解一下三者的区别,可以有选择的去学习!
547 0
史上最全的LED点灯程序—使用STM32、FPGA、Linux点亮你的LED灯
|
机器学习/深度学习 人工智能 文字识别
预约直播 | 主流视觉算法介绍及在PAI上的应用
阿里云AI技术分享会第一期《主流视觉算法介绍及在PAI上的应用》将在2022年06月30日开启直播,精彩不容错过!
预约直播 | 主流视觉算法介绍及在PAI上的应用