设有如下的定义:
short score[10]={1,3,5,7,9,11,13,15,17,19};
long int *ps = (long *) score
那么,表达式 ps+2 的值和以下哪几项取值相同?与哪一项不仅取值相同,类型也相同?为什么?
(1)score (2)(long int *)score (3)score+2 (4)(long int *)(score+2)
(5)score+4 (4)(long int *)(score+4)
解答
为了回答这个问题,我们需要理解一些关于指针运算和类型转换的基础知识。特别是,当指针类型不同,它们指向的内存地址会有所不同。
首先,我们来看一下 ps
的定义:
short score[10] = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
long int *ps = (long int *) score;
ps
是一个指向 long int
的指针,但它被初始化为指向 score
数组的首地址。由于 score
是一个 short
数组,这里的类型转换是将 score
的地址视为指向 long int
类型。
指针运算的解释
-
原始数组的布局:
score
数组的内存布局是连续的,每个short
类型占用 2 个字节。- 因此,
score
数组中的元素在内存中的排列是:score: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] 地址: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] (每个元素占2字节)
-
long int *ps = (long int *)score
:- 这条语句将
score
的首地址视为long int
类型的指针。 long int
通常占用 4 个字节(在大多数平台上),所以ps
认为每个元素跨度是 4 个字节。
- 这条语句将
-
ps + 2
:ps
是一个long int
类型的指针,所以ps + 2
实际上是移动两个long int
的跨度,即 2 * 4 = 8 个字节。- 因此,
ps + 2
将指向score
数组起始地址偏移 8 个字节的位置,即score + 4
。
与选项比较
我们现在比较一下 ps + 2
与各个选项的值和类型:
-
score
:- 值:
score
是数组的首地址,即起始地址。 - 类型:
short*
。
- 值:
-
(long int *)score
:- 值:数组的首地址,但类型转换为
long int*
。 - 类型:
long int*
。
- 值:数组的首地址,但类型转换为
-
score + 2
:- 值:
score
起始地址偏移 2 个short
,即偏移 4 个字节。 - 类型:
short*
。
- 值:
-
(long int *)(score + 2)
:- 值:
score + 2
的地址,类型转换为long int*
。 - 类型:
long int*
。 - 这个值指向
score
起始地址偏移 4 个字节(short
的大小 * 2)。
- 值:
-
score + 4
:- 值:
score
起始地址偏移 4 个short
,即偏移 8 个字节。 - 类型:
short*
。
- 值:
-
(long int *)(score + 4)
:- 值:
score + 4
的地址,类型转换为long int*
。 - 类型:
long int*
。 - 这个值指向
score
起始地址偏移 8 个字节(short
的大小 * 4)。
- 值:
结果分析
-
与
ps + 2
取值相同:- 取值相同的项是
score + 4
和(long int *)(score + 4)
,因为它们都指向score
起始地址偏移 8 个字节的位置。
- 取值相同的项是
-
与
ps + 2
取值和类型都相同:- 与
ps + 2
取值和类型都相同的项是(long int *)(score + 4)
。因为ps
是long int*
类型,ps + 2
指向score
起始地址偏移 8 个字节的位置。
- 与
最终结论
- 取值相同的项:
score + 4
和(long int *)(score + 4)
- 取值和类型都相同的项:
(long int *)(score + 4)