写在前面的话:本文章的内容是对王利涛老师的《C语言嵌入式Linux编程》系列课程的学习笔记,王老师讲得很好,清晰易懂,写这个博客仅处于学习用途。
目录
下标运算符
对数组的打印有几种方式
为什么指针可以使用[]访问数组?p[i]
为什么数组可以使用*访问数组元素?*(a+i)
下标运算符
数组名的本质
底层实现机制
为什么对数组直接赋值?为什么只有在初始化的时候赋值?
数组名的本质
指针数组与数组指针
指针数组的数组元素是指针 char *season[4] ([]有更高的优先级)
数组指针是指向数组的指针 int(*pa)[4]
小结
下标运算符
指针和数组是不同的数据类型
对数组的打印有几种方式
#include "stdio.h"
int main(){
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p=a;
for(int i=0;i<10;i++){
printf("%d ",a[i]);
}
printf("
");
for(int i=0;i<10;i++){
printf("%d ",*(a+i));
}
printf("
");
for(int i=0;i<10;i++){
printf("%d ",*(p+i));
}
printf("
");
for(int i=0;i<10;i++){
printf("%d ",p[i]);
}
}
运行的结果完全一样
并且当函数传参是一个数组时,传入一个数组名还是指针名的效果也是完全一样的
为什么指针可以使用[]访问数组?p[i]
为什么数组可以使用*访问数组元素?*(a+i)
下标运算符
因为C语言对
下标运算符[]有如下的操作:E1[E2] ---> *(E1+E2) 也就是a[i] -->*(a+i)所以可以通用
因为对E1和E2没有正负限制,所以可以有如下的定义
下标运算符[]和不仅和数组有关
int i =10;
int *p=&i;
printf("%d
",1[&i-1] ==> *(1+&i-1) ==> *(&i) ==>10
数组名的本质
数组名代表了什么?底层如何实现?传参传了什么?
底层实现机制
传入的参数在arm中会先放入r0~r3,其余的才会放到栈中
- ldr r0, [pc,#16] ; 104d8 是寄存器简介寻址,将104d8地址上的内容放入r0这个寄存器里面
在104d8中存在一个地址,00021028
- 所以在传递参数的时候,是传递数组的首地址
- 数组名是不等于常量指针的
数组名是有类型的,是不同的数据类型,传递的地址相同,碗和杯子装水的例子
老师举的例子
&a+1 ==> &a+1*(sizeof(a))
为什么对数组直接赋值?为什么只有在初始化的时候赋值?
数组名的隐式转换
(在不同的时期有不同的意义)
数组名的本质
对于int b[4][20]而言,其实是一个有4个元素的一维数组,每一个数组元素都是有20个int组成的一维数组
所以int (*q)[20] 就是一个指针数组,指向的元素是元素有20个int的一维数组
指针数组与数组指针
指针数组的数组元素是指针 char *season[4] ([]有更高的优先级)
char *season[4] = {"spring","summer","autumn","winter"};
printf("hello %s",season[i])
- 字符串在C语言中存放于rodata段中
- 这个数组里存放的是字符串的元素的首地址
数组指针是指向数组的指针 int(*pa)[4]
对于一维数组是数组首元素的地址,对于二维数组传递是首元素地址,
首元素是一个指向数组的指针
int main(void)
int main(int argc, char *argv[]) 是一个指针数组
小结
听完这节课之后,我对指针和数组有了更清楚的了解。并且项目中遇到的一些不清楚的表达也清晰了很多。我觉得最近自己的记忆力在衰退,很多东西都是看了,理解了但是还是会忘记,还是要多多复习呢,多多动手!