数组与指针
本文帮助大家记忆数组的相关知识
问题引出:
int b[10];
b[0]的类型是?b[0]的值为
b的类型是?b的值为多少?
b[0]和b都是变量的标识符,所以他们有自身的值和地址
我们知道b[0]代表数组b中第一个元素,它的类型毫无疑问是int类型,它的值还未定义,假如是全局变量,值初始化为0,局部变量为随机值
为了方便,牢记下面的规则。我们不必再继续深究下去为什么会这样,因为编译器就是这么工作。
b为一个指针常量(常量放在静态存储区),值为数组中第一个元素的地址。数组名的类型取决于数组元素类型,该题数组元素类型为int,所以b的类型为“指向int类型的指针”,也就是int *类型
PS:如果大家能够理解上面的解释,本文就不必看了。
进阶
那么更加复杂的类型呢?
比如
int b[3][4];
int c[3][4][5];
画一个图方便大家理解,我们知道多维数组在内存中也是线性存储。栈区内存模型如上图所示。
注:箭头表示指向,例如第一个箭头表示b[0]的值为某个地址,指向下面那一个位置。
b[0][0]
就是上方一小格内存块的别名。
b[0]、b[1]、b[2]表示的是数组b的三个元素
根据b的定义,b是一个数组名
问题1
b的值为多少?
第一个元素的地址为&b[0]
b的类型呢?
因为b[0]本身是一个数组,所以b的类型为指向b[0]这种类型的指针,也就是int (*)[4]
问题2
那么b[0]的值是多少?
b[0]其实也是一个数组名,值为第一个元素的地址,也就是&b[0][0]
b[0]的类型呢?
b[0]中的数组元素类型为int类型,b的类型为指向int类型的指针,所以b[0]的类型为int *
–
也就是说b b[0] &b[0] &b[0][0]
的值都相同,大家细品
数组与指针运算结合
回顾指针的运算
指针 + 整数 X sizeof(指针指向的类型)
int d[4][5];
int (*p)[5] = d;
int *pp = d[0];
问题3
d的类型?
int (*)[5]
p的类型?
int (*)[5]
d[0]的类型?
int *
&d[0]的类型?
int (*)[5]
&p的类型?
是int (**)[5]
还是 int (*)[4][5]
?
int (**)[5]
&d的类型?
int (*)[4][5]
问题4
假设d的值为100,int占4个字节,回答下面问题
还有哪些值为100的变量?
d、 &d[0]
、&d[0][0]
、p 、pp
问题5
假设d的值为100,int占4个字节,写出下面表达式的值
d + 2 ?
d指向的类型为d[0]的类型,含有5个int元素
100 + 2 * 5 * 4
p + 2?
100 + 2 * 5 * 4
d[0] + 2?
d[0]的类型为int *, 指向的类型为int
100 + 2 * 4
&d[0] + 2?
相当于d + 2
100 + 2 * 5 * 4
&d + 2
&d指向的类型为,d的类型,含有4 * 5个int类型
d + 2 * 4 * 5 * 4
总结
记住两条规则
①
数组名为一个指针常量,值为数组中第一个元素的地址。
数组名的类型取决于数组元素类型,假设数组元素类型为int,
数组名的类型为“指向该类型的指针”
②
指针 + 整数 X sizeof(指针指向的类型)
也就是说对数组名进行加减操作时,看数组的元素是什么就ok啦
至于其他的指针,看它指向的是什么类型就ok
指针运算规则,可以参考我的另一篇博客
PPS:
如果对大家有帮助,点赞加收藏哟~