以下题目皆是在x64的环境下进行。

一,整形数组

先定义一个整形数组:

指针与数组笔试题解析_数组

求下列各题打印结果:

指针与数组笔试题解析_数组名_02

一般情况下,数组名代表的是首元素的地址,但是如果是sizeof(数组名)的形式,数组名单独放在sizeof()内,此时数组名代表的是整个数组,所以此时sizeof()所求的是整个数组所占内存的大小,大小为16个字节

指针与数组笔试题解析_数组_03

这一题数组名并没有单独放在sizeof()里,所以a代表的是首元素的地址,a+0依旧是首元素的地址,而地址在x64的环境下所占的内存都是8个字节(如果在x86的环境下,地址所占内存大小为4个字节)。

指针与数组笔试题解析_数组_04

这一题就相当于是sizeof(*(a+0)),即sizeof(a[0]),所以sizeof()所求的是a[0]所占内存的大小大小,为4个字节

指针与数组笔试题解析_数组名_05

这一题数组名没有单独放在sizeof()里,a代表的是首元素的地址,a+1代表的是数组中第二个元素的地址,既然是地址,那么在x64的环境下所占内存大小就是8个字节

指针与数组笔试题解析_数组名_06

这一题显而易见所求的就是数组中a[1]所占内存大小,即4个字节

指针与数组笔试题解析_字符串_07

数组名取地址,取的是整个数组的地址,既然是地址,在x64的环境下所占内存就是8个字节

指针与数组笔试题解析_数组_08

先对数组a取地址,取出整个数组的地址,然后再解引用,也就得到了整个数组,所以此时所求的的是整个数组所占内存的大小16个字节。其实也可以理解为*与&可以相互抵消了,所以这题也就相当于是sizeof(a)。

指针与数组笔试题解析_数组_09

取数组a的地址,再+1,得到的还是一个地址,所占内存大小也时8个字节。&a + 1跳过了一整个数组,也就是16个字节,此时已经超出了这个数组的范围,但是因为sizeof内部不会进行实际运算,所以不会出现越界。

指针与数组笔试题解析_数组名_10

取a[0]这个元素的地址,所占内存大小为8个字节

指针与数组笔试题解析_字符串_11

取a[0]的地址,再+1,得到的是a[1]的地址,所占内存大小为8个字节

二,字符数组

先定义一个字符数组:

指针与数组笔试题解析_数组_12

求下列各题打印结果:

指针与数组笔试题解析_数组名_13

这题这之前的题目一样,arr单独放在sizeof()里,所求的是整个数组所占内存的大小,6个字节

指针与数组笔试题解析_数组名_14

arr并没有单独放在sizeof()里,所以arr代表的是首元素的地址,arr+0依旧是首元素的地址,所占内存大小为8个字节

指针与数组笔试题解析_数组_15

这一题就相当于是sizeof(*(a+0)),即sizeof(a[0]),所以sizeof()所求的是a[0]所占内存的大小大小为1个字节。

指针与数组笔试题解析_数组名_16

这题所求的就是数组中元素a[1]所占内存大小,即为1个字节

指针与数组笔试题解析_字符串_17

&arr取出的是整个数组的地址,既然是地址,那么所占内存大小就是8个字节

指针与数组笔试题解析_字符串_18

&arr取的是整个数组的地址,然后再+1,跳过了整个数组6个字节,指向的还是一个地址,所站内存就是8个字节

指针与数组笔试题解析_字符串_19

&arr[0]+1,也就相当于&arr[1],也是一个地址,所占内存大小为8个字节

指针与数组笔试题解析_数组名_20

strlrn是用来计算字符串长度的库函数,原理是传入一个地址,从这个地址开始向后遍历,每次跳过一个字节,在遇到\0时停下。我们在定义字符串时,系统会自动在字符串末尾加上\0,但是在字符数组中,则不会自动加上\0,上面我们定义的字符数组并没有\0。当我们把arr也就是首元素地址传给strlen时,strlen会从arr[0]开始向后遍历,遍历到数组最后依旧没有遇到\0,就会继续向后查找,直到遇到\0才停下,由于我们不知道什么时候才知道会遇到\0,所以此时strlen()所求出的长度是一个随机值。设这个随机值为n。

指针与数组笔试题解析_字符串_21

这题其实和上一题是一样的,也是把arr[0]的的值传给strlen,所以这题所求的出的长度也是一个的随机值。这个随机值也是n,和上一题相同。

指针与数组笔试题解析_数组名_22

这题我们把*arr传给了strlen(),*arr是也就是arr[0],是一个字符,但是我们知道,strlen()函数要求传给它的参数是一个地址,如果我们把一个字符传给它,那么系统就会报错,提示非法访问

指针与数组笔试题解析_数组名_23

这题和上面一道题类似,也是传了一个字符作为参数给strlen(),系统报错,提示非法访问

指针与数组笔试题解析_数组名_24

这题我们把整个数组的地址传给了strlen(),虽然是整个数组的地址,但是指向的还是arr[0],是一个数组指针,当传给stelen()后,strlrn的形参形式是const char*,所以系统会把数组指针当成字符指针来处理,所以还是从arr[0]开始向后遍历,每次跳过一个字节,所求长度是一个随机值,并且和第8、第9题结果一样为n。

指针与数组笔试题解析_数组名_25

&arr取的是整个数组的地址,+1则是跳过了整个数组6个字节,把数组地址作位参数传给strlen(),和上一题是一样的,只不过这题strlen()是从arr[5]的后一个地址开始向后遍历,所求长度是一个随机值,并且结果为n-6。

指针与数组笔试题解析_字符串_26

&arr[0]+1,其实就是&arr[1],把arr[1]的地址作位参数传给strlen(),从arr[1]开始向后遍历,所求长度是个随机值,并且结果结果为n-1。

三,字符串

先定义一个字符串:

指针与数组笔试题解析_字符串_27

求下列各题打印结果:

指针与数组笔试题解析_数组_28

这题求的是整个字符串所占内存大小,这题我们定义的是字符串,系统在末尾自动添上\0,所以整个字符串所占内存大小为7个字节

指针与数组笔试题解析_数组_29

arr没有单独放在sizeof()内,所以arr代表首元素的地址,arr+0,还是首元素的地址,所占内存大小为8个字节

指针与数组笔试题解析_数组名_30

这题相当于sizeof(a[0]),求的是a[0]所占内存大小,为1个字节

指针与数组笔试题解析_数组名_31

这题所求就是字符串中元素a[1]所占内存大小,为1个字节

指针与数组笔试题解析_字符串_32

&arr取出的是整个字符串的地址,既然是地址,所占内存大小就是8个字节

指针与数组笔试题解析_数组_33

这题就是先取整个字符串的地址,然后再+1,跳过了一个7个字节,指向了arr[6]的后一个地址,所占内存大小为8个字节

指针与数组笔试题解析_字符串_34

这一题先取arr[0]的地址,然后再+1,得到的是arr[1]的地址,所占内存大小为8个字节

指针与数组笔试题解析_数组_35

arr代表的是首元素地址,这次我们定义的是字符串,第7个元素是\0,所以求出的长度为6

指针与数组笔试题解析_字符串_36

这一题和上题一样,arr+0还是代表首元素的地址,所以求出的长度为6

指针与数组笔试题解析_数组名_37

strlen()要求形参类型为字符指针(一个地址),*arr相当于是arr[0],把字符串的一个元素作位参数传给strlen()函数,系统会报错,提示非法访问

指针与数组笔试题解析_数组名_38

这一题和上一题一样,把字符串的元素作为参数从传给了strlen()函数,系统报错,提示非法访问

指针与数组笔试题解析_数组名_39

这题我们把整个字符串的地址传给了strlen(),虽然是整个字符串的地址,但是指向的还是arr[0],当传给strlen()后,strlrn的形参形式是const char*,所以系统会把数组指针当成字符指针来处理,所以还是从arr[0]开始向后遍历,每次跳过1个字节,当遍历到arr[6]也就是\0时,就停止了,返回求到的字符串长度,长度为6

指针与数组笔试题解析_字符串_40

这题就是先取整个字符串的地址,然后再 + 1,跳过了7个字节,指向了arr[6]的后一个地址,把这个地址作为参数传给strlen()函数。和上一题一样,strlen()函数从arr[6]的后一个地址开始向后遍历,知道遇到\0才停止,我们并不知道什么时候才能遇到\0,所以所求长度为随机值

指针与数组笔试题解析_数组_41

这一题是吧&arr[0]+1,也就是&arr[1]作为参数传给strlen(),strlen()从arr[1]开始向后遍历,遇到arr[6]也就是\0时停止,返回字符串长度为5

四,二维数组

先定义一个二维数组:

指针与数组笔试题解析_数组名_42

关于二维数组,我们要知道,二维数组的数组名指的首元素其实是第一行的数组,例如上面定义的二维数组,它的数组名a代表的首元素是数组a[0]。同时,这个二维数组第一行数组的数组名a[0]代表的首元素是a[0][0]。

求下列各题打印结果:

指针与数组笔试题解析_字符串_43

a是二维数组的数组名,单独放在sizeof()内,代表的是整个二维数组,所占内存大小为48个字节

指针与数组笔试题解析_字符串_44

这一题所求的就是二维数组中元素a[0][0]所占内存大小,为4个字节

指针与数组笔试题解析_数组_45

a[0]是a这个二维数组中第一行的数组的数组名,数组名单独放在sizeof()内,代表的是整个数组,第一行的数组所占内存大小为16个字节

指针与数组笔试题解析_字符串_46

a[0]是第一行数组的数组名,代表的是第一行数组首元素的地址,也就是相当于&a[0][0],而a[0]+1,就相当于&a[0][1],也是一个地址,所占内存大小为8个字节

指针与数组笔试题解析_字符串_47

a[0]+1相当于&a[0][1],再解引用,也就是求a[0][1]所占内存大小,为4个字节

指针与数组笔试题解析_数组_48

a是二维数组的数组名,代表的是首元素的地址,二维数组的首元素也就是第一行数组。第一行数组的地址+1,也就是第二行数组的地址,既然是地址,所占内存大小就是8个字节

指针与数组笔试题解析_数组_49

承接上题,a+1是第二行数组的地址,再解引用,就是第二行整个数组,所占内存大小为16个字节

指针与数组笔试题解析_数组_50

&a[0]取的是第一行整个数组的地址,再加1,就是第二行整个数组的地址,所占内存大小为8个字节

指针与数组笔试题解析_字符串_51

承接上题,&a[0]+1是第二行整个数组的地址,再解引用,就是第二行整个数组,所占内存大小为16个字节

指针与数组笔试题解析_字符串_52

a是二维数组的数组名,代表的是首元素也就是第一行元素的地址,再解引用,也就是第一行的所有元素,所占内存大小为16个字节

指针与数组笔试题解析_字符串_53

a[3]是第四行数组的数组名,但是我们定义的二维数组只有三行,按理来说已经越界了。但是因为sizeof内部的表达式不会真正的访问(计算),只要能确定sizeof()内部表达式的类型就可以了,不需要计算,所以这题并不存在越界访问,所以a[3]所占内存大小为16个字节

总结:

数组名的意义:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。


新手上路,请多指教。