单片机视角理解指针与数组
从图四可以看到因为我使用的是STM32所以地址总线是32位那么任何类型的指针的大小都是4个字节的。而这些类型的指针保存的都是这些变量的首地址而这些首地址都是32位的也就是4个字节从这个图我们可以知道这个指针pa意思就是p这个地址的值等于a的地址。所以指针变量 p 本身它也是一个变量有自己的内存地址图里 p 0x20000450这个地址里存储的 “内容 / 值”是另一个内存的地址。而p a 的含义就是把变量 a 的地址0x20000454赋值给指针变量 p也就是p 这个变量里存储的值 a 的地址。** *p 0x12345678 **的意思就是先取出指针变量 p 里存的值0x20000454也就是 a 的地址然后把这个数值当成内存地址找到 0x20000454 开头的 4 字节int 类型占 4 字节内存空间把 0x12345678数据写入到这个内存空间里指针操控硬件这两个图解释了指针如何操控硬件先定义一个指针然后将寄存器的地址赋给这个指针指针就能够访问这个地址写入数据来操控这个寄存器对应的硬件比如图一就是将控制 LED 引脚的 GPIO 外设的输出数据寄存器ODR的地址赋给指针然后指针将0这个数据写入到LED灯的地址去然后拉低了控制LED灯的引脚实现了开灯的功能。volatile 的作用就是告诉编译器每次访问这个地址都必须老老实实去读写真实的物理地址禁止做优化、禁止缓存值保证每次读写都真实作用到硬件上。指针类型的选择虽然这些类型的指针本身占的内存大小相同但每种类型的指针一次操作的字节的大小不同char* 1个字节 short * 2个字节 int* 4个字节它们的起始地址大小都相同都是4个字节但** *指针从这个起始地址起能读取/写入的字节大小**不同例如上面这个图如果想用指针来访问一个寄存器的地址同样的40021414地址int*类型指针就能访问这一整个32位寄存器如果用char*类型指针就只能访问低8位即一个字节想访问下个字节就要用40021415数组数组就是一块连续的空间这空间有十个每个都是char大小图片上数组b[10]就是10个char类型的空间。如果数组b[3]没有赋值那么打印字符串的时候它是从前到后打印在第四位的时候遇到0它会以为结束了所以就不会打印出w。这里要注意的是如果给一个数组赋值那么在结尾要加上’/0’因为printf(“%s”, 数组名) 打印字符串时必须遇见 \0ASCII 0字符串终止符才停止输出。找不到\0就会越界继续向后读取内存出现随机乱码。而且注意的是’/0’也占一块空间即在char数组占一个字节大小