解锁即可观看《物联网/嵌入式工程师》完整课程视频

物联网/嵌入式工程师

面向零基础保姆式教学+简历指导+1V1模拟面试+3次内推,助力轻松就业!

【第0周】物联网/嵌入式工程师就业班开学典礼
【第1周】嵌入式开发基石-计算机基础与C语言
【第2周】C语言进阶-编程思想
【第3周】C语言高级进阶
【第4周】C语言项目实战与《阶段笔试》
【第5周】数据结构-线性结构
【第6周】数据结构-非线性结构
【第7周】排序与复杂度
【第8周】数据结构项目实战
【第9周】Shell编程和Makefile工程管理
【第10周】Linux文件IO和标准IO
【第11周】Linux下文件操作项目实践与阶段评测
【第12周】Linux 多进程、多线程、IO模型
【第13周】Linux 项目实战-实现并发服务器模型与企业笔试
【第14周】网络基础和UDP Socket编程
【第15周】TCP Socket编程和WireShark抓包分析
【第16周】网络编程项目实战-网络视频监控与企业笔试
【第17周】从C到C++
【第18周】软件设计模式与C++11新特性
【第19周】项目实战-C++语言实现五子棋游戏与企业笔试
【第20周】嵌入式产品人机交互必备-QT框架
【第21周】项目实战-QT开发音乐播放器
【第22周】智能硬件开发-ARM核介绍和基础外设
【第23周】智能硬件开发-单片机常用外设
【第24周】stm32芯片-智能硬件项目实战与企业笔试
【第25周】大厂必备- linux内核与文件系统移植
【第26周】嵌入式开发-系统移植-bootloader、yocto
【第27周】嵌入式底层核心技能-Linux设备驱动初级
【第28周】嵌入式底层核心技能-Linux设备驱动中级
【第29周】嵌入式底层核心技能-Linux设备驱动高级1
【第30周】嵌入式底层核心技能-Linux设备驱动高级2
【第31周】智能家居项目实战之Linux智能网关端开发
【第32周】智能家居项目实战之STM32单片机设备端开发
【第33周】人脸指纹识别考勤机设计与实战
【第34周】物联网/嵌入式项目答辩和就业指导
【第35周】独立开发阶段-三大热门领域项目
【第36周】硬件电路设计-电路基础知识
【第37周】STM32最小系统 - 硬件电路设计实战项目(一)
【第38周】CAN总线分析仪 - 硬件电路设计实战项目(二)
【第39周】4路输入输出控制器 - 硬件电路设计实战项目(三)
【第40周】8路逻辑分析仪 - 硬件电路设计实战项目(四)
章节
问答
课签
笔记
评论
占位
占位

指针和数组的姻缘

数组篇

在前面及小结中,我们学习了指针和数组的概念,看起来这是两个完全不同的东西。但其实他们两者是紧密相关的,本小结我们就来探讨一下指针和数组的联系。

我们在定义数组的时候,常常这样定义,int arr[5];

在 C++ 中,数组表示的是一段连续的内存存储空间

如上图,每个元素之间是没有空隙的,这样每个元素的内存地址,其实也是有规律可循的。可以写这样一个程序,来验证我们的想法:

#include <stdio.h>

int main(int argc,char **argv)
{
    int array[5];
    printf("array[0]: %p\n", &array[0]); // %p 用来打印数组的地址
    printf("array[1]: %p\n", &array[1]);
    printf("array[2]: %p\n", &array[2]);
    printf("array[3]: %p\n", &array[3]);
    printf("array[4]: %p\n", &array[4]);

    return 0;
}

程序运行结果如下:

array[0]: 0x7ffee9d81490
array[1]: 0x7ffee9d81494
array[2]: 0x7ffee9d81498
array[3]: 0x7ffee9d8149c
array[4]: 0x7ffee9d814a0

指针的地址以16进制的方式输出,可以看出,这几个地址中,每两个相邻的地址都相差 4 ,而每一个元素都是 int类型,int 占 4 个字节大小,说明他们确实是紧密相连的。

验证了数组的地址之后,再来看看数组是如何访问数组中的元素的。假设我们想要访问第 2 个元素(从 0 开始)

array[1];

那么 C++ 在碰到这行代码的时候,是先拿到第 2 个元素的地址,然后通过地址去访问元素,那么如何拿到第二个元素的地址呢?刚刚的实验证明,数组中元素的地址都是等差的,所以只要拿到第一个元素的地址,再加上相应元素的偏差,就可以拿到第二个元素的地址了。

那么,对于数组来说,第一个元素的地址是什么的?答案是数组名。

我们再尝试写一个测试程序

#include <stdio.h>

int main(int argc,char **argv)
{
    int array[5];
    printf("array: %p\n", array);
    printf("array[0]: %p\n", &array[0]); // %p 用来打印数组的地址
    printf("array[1]: %p\n", &array[1]);
    printf("array[2]: %p\n", &array[2]);
    printf("array[3]: %p\n", &array[3]);
    printf("array[4]: %p\n", &array[4]);

    return 0;
}

程序运行结果如下:

array: 0x7ffeefa29490
array[0]: 0x7ffeefa29490
array[1]: 0x7ffeefa29494
array[2]: 0x7ffeefa29498
array[3]: 0x7ffeefa2949c
array[4]: 0x7ffeefa294a0

我们发现,直接输出 array 和首元素的地址,是一模一样的,那么就可以得出一个结论:数组名是一个指向数组首元素的指针

但是这个指针和我们常见的指针有一些不一样的地方,这个指针是一个常量,所以我们是不可以对其进行修改的。也就是说,我们不能对其进行 array = p 或者 array++ 这样包含重新赋值的操作,但是我们仍然可以用指针的用法来操作他。

例如,使用指针的加减法来访问对应的元素

#include <stdio.h>

int main(int argc,char **argv)
{
    int array[5];
    *(array + 2) = 1;

    return 0;
}

代码中的 *(array + 2) = 1; 就等价于 array[2] = 1;

指针篇

我们在前面讲过 malloc 分配内存的用法。来看一个例子

#include <stdio.h>

int main(int argc,char **argv)
{
    int * p = (int *)malloc(5 * sizeof(int));

    free(p);
    return 0;
}

在上面的程序中,我们分配出来了一个 5 个 int 大小的储存空间:

在这块储存空间内,可以存放 5 个 int 类型的数字,假如想要访问第 3 个数字,我们可以把指针向后移动两个元素的位置,写成 *(p + 2)

那么指针可不可以按照数组的访问方式去访问呢?p[2]

其实也是可以的,p[2]*(p + 2)在这里是等价的。

任务

?不会了怎么办
||

提问题

写笔记

公开笔记
提交
||

请验证,完成请求

由于请求次数过多,请先验证,完成再次请求

加群二维码

打开微信扫码自动绑定

您还未绑定服务号

绑定后可得到

  • · 粉丝专属优惠福利
  • · 大咖直播交流干货
  • · 课程更新,问题答复提醒
  • · 账号支付安全提醒

收藏课程后,能更快找到我哦~

使用 Ctrl+D 可将课程添加到书签

邀请您关注公众号
关注后,及时获悉本课程动态

举报

0/150
提交
取消
全部 精华 我要发布
全部 我要发布
最热 最新
只看我的

手记推荐

更多

本次提问将花费2个积分

你的积分不足,无法发表

为什么扣积分?

本次提问将花费2个积分

继续发表请点击 "确定"

为什么扣积分?