C语言指针的个人见解(二)

C语言指针的个人见解(二)


1.关于数组

1.1什么是数组

在C语言中,数组指的是一系列相同数据组成的集合
数组有以下性质

  1. 除去变长数组之外,声明数组的时候数组的大小必须由常量提供
  2. 数组的大小在声明之后不可更改
  3. C语言不对越界做处理,需要coder自己注意
  4. 数组名在使用上可以当做是指向数组第一个元素的该类型的指针

数组的元素有如下性质

  1. 每个元素的类型都相同
  2. 元素名被隐藏,通过首地址+索引来找到元素
  3. 因为类型相同,可知元素储存时所需的内存、字节数也相同
  4. 在C语言中,数组的元素在内存中的排列是紧挨着的,并且地址依次递增

1.2数组举例

假设有int a[3]={0,1,2}
a[3]中的三个元素的地址和如下举例有相同性质

a[0]:007FFE20 007FFE21 007FFE22 007FFE23
a[1]:007FFE24 007FFE25 007FFE26 007FFE27
a[2]:007FFE28 007FFE29 007FFE30 007FFE31

可以看见最后两位是依次++的

1.3指针与数组名

还是使用上面的例子

1
2
int a[3] = {0,1,2};
int* int_pa = a;

在这个前提下,会发现几个基本等价的语句

1
2
3
a[i];
int_pa[i];
*(int_pa+i)

C语言指针的个人见解(一)中,已经讲过指针自增的效果
当int_pa指向a[0]时,int_pa的值就是007FFE20
所以(int_pa+1)的值就是007FFE24,也就是a[1]的地址,这个时候使用*解引用,自然就拿到了a[1]

再复杂一点,下面几个也是等价的

1
2
3
4
5
*(*(*(*(X+i)+j)+k)+t);
*(*(*(X[i]+j)+k)+t);
*(*(X[i][j]+k)+t);
*(X[i][j][k]+t);
X[i][j][k][t];

1.4指针数组与数组指针

众所周知,读书要从右到左(滑稽)
所以指针数组就是指针组成的数组,是个数组
所以数组指针就是指向数组的指针,是个指针

1
2
3
4
5
6
7
8
9
int *pa[3];//指针数组
//这样用
int a[3] = {0,1,2}
pa[0] = a + 0;
pa[1] = a + 1;
pa[2] = a + 2;
//之后就有以下几组等价的语句
*pa[0]和a[0]
**(pa+1)和a[1]

可以画个图理解一下

1
2
3
4
int (*pa)[3];//数组指针
//这样用
int a[3][3];
pa = a;

画图理解的时候,指针不要只画一个箭头,建议在箭头的重点把指针指向的内容用圈圈括起来,比如这个,就要把一整行都圈起来。(a[0][0],a[0][1],a[0][2]这一行)

在上一次的文章中已经讲过,这里类似理解
pa指向的类型是三个int组成的数组

a[0][0]:007FFE20 007FFE21 007FFE22 007FFE23
a[0][1]:007FFE24 007FFE25 007FFE26 007FFE27
a[0][2]:007FFE28 007FFE29 007FFE30 007FFE31

那么pa就要把这十二个字节都括起来
当pa++时,pa的值变为007FFE32

所以万变不离其宗,不管指针指向的是什么乱七八糟的玩意儿,指针的几条性质是不会变的。
这里可以思考一下在把一整个数组当做参数传递的时候的指针的使用

下一期就谈一谈函数指针,好了,开始拖更