指针课后习题
判断题
第一题
从内存单元中存取数据的方法有直接访问方式和间接访问方式。
知识点:
- 内存单元的数据存取方式 【书 P186】
答案与分析
正确
分析
- 直接访问方式:通过变量名存取变量内容。
如
a = 2
、cout << a
。 - 间接访问方式:通过 地址(即指针) 操作。
如
*a = 5
、cout << *a
。
第二题
能够直接赋值给指针变量的整数是$0$和$1$。
知识点:
- 指针赋值 【书 P187】
答案与分析
错误
分析
整数中,只有$0$才可以赋值指针,代表空地址(NULL
)。
书上原话
“地址”,可以是变量的地址、数组名、函数名等,也可以是数值$0$(或NULL
)。
没有任何对象会被分配到地址0
(或NULL
),因此数值$0$(或NULL
)是可以直接赋给指针变量的唯一整数。
第四题
“变量的指针”含义是指该变量的地址。
个人做错了这道题!
为一道很新颖的概念题。
答案与分析
正确
分析
纯概念题,记住!
第九题
在操作一个一维数组时,可能会用到两个指针变量指向该数组,
这两个指针变量之间可以进行关系运算,其关系运算的结果表明了这两个指针变量所指向的数组元素的先后关系。
个人做错了这道题!
为一道很新颖的概念题。
【个人甚至都不知道这种方法……
知识点:
- 指向一维数组的指针的关系运算 【书 P190】
答案与分析
正确
分析
当有两个指针指向同一个数组时,
可以对这两个指针进行比较(<
、>
),以反应这两个指针的位置关系。
例子
假设:
存在数组int a[10]
,
存在两个指针int *p1,*p2
。
这两个指针均指向数组a
中某个位置(如p1=&a[4]
,p2=&a[8]
)
- 若
p1 < p2
,则代表p1
所指向的数组元素,在p2
所指向的数组元素前面。 - 若
p1 = p2
,则代表p1
、p2
指向数组中同一个元素。 - 若
p1 > p2
,则代表p1
所指向的数组元素,在p2
所指向的数组元素后面。
具体可以看书上,有图示来解释。
第十题
对于已经定义好的相同类型的两个指针变量,可以进行加法运算、减法运算和赋值运算。
个人做错了这道题!
为一道很新颖的概念题。
【个人甚至都不知道这种方法……
知识点:
- 指针间的运算 【书上没找到对应知识点】
答案与分析
错误
分析
指针间存在三种运算。
假设两指针
int *a,*b
。
- 赋值运算(
a = b
)
代表最基本的赋值。- 关系运算(
a < b
)
代表a
和b
位置关系。【一般用于数组中,代表谁指向前面谁指向后面】- 减法运算(
a - b
) 代表a
到b
之间的距离。【一般用于数组中,如a = &arr[5]
,b =& arr[7]
,则a-b
为$2$】
上述题错在:没有加法运算。
第十九题
使用动态储存分配时,用运算符new
获取的内存空间,不必须用delete
进行释放。
个人做错了这道题!
为一道很新颖的概念题。
知识点:
- 动态存储分配 【书 P201】
答案与分析
错误
分析
纯概念题,记住!
书上原话
用new
获取的内存空间,必须用delete
运算进行释放,并且对同一个内存空间只能执行一次delete
。
【虽然个人感觉确实不用的,因为程序结束会自动帮你释放xd……
注意只能delete一次
第二十二题
设int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}, (*p)[5];
,
则使用p = a
语句是不合法的。
个人做错了这道题!
知识点:
- 数组指针变量 【书 P196】
答案与分析
错误
分析
个人暂时也不知道原因,正在询问老师【……
感觉是题目错了……
选择题
第三十三、三十四、三十七、三十八题
因为这几道题考点相同,故放在一起形成对照。【区别仅在++
的位置】
设有如下程序段,输出的值为()
int x = 8, *p = &x;
cout << *p++ << endl;
A. $8$
B. $9$
C. $8$的地址
D. $9$的地址
答案与分析
A. 8
分析
这里面先是运算*p
,得到值$8$,
然后就变成了cout << 8++ << endl;
,这个时候就是先返回结果再运算。
也就是先输出$8$,然后再*p = *p + 1
变成$9$。
设有如下程序段,输出的值为()
int x = 8, *p = &x;
cout << ++*p << endl;
A. $8$
B. $9$
C. $8$的地址
D. $9$的地址
答案与分析
B. 9
分析
注意这里面还是先运算*p
,得到值$8$,
然后就变成了cout << ++8 << endl;
,这个时候就变成了先运算再返回结果。
也就是先*p = *p + 1
变成$9$,然后再输出$9$。
总之前两道题,都是先运算*p
。
设有定义语句:
int a[10]={0,1,2,3,4,5,6,7,8,9},*p = a;
则数值不为$3$的表达式为()。
A. a[3]
B. p[3]
C. p += 2, *(p++)
D. p += 2, *(++p)
个人做错了这道题!
为一道很容易错的操作题。
答案与分析
D. p += 2, *(++p)
分析
首先A、B选项,直接能看出a[3]
和p[3]
均为数组第四个元素,即为$3$。
所以讨论C、D选项。
注意这里的指针,变成了指向数组的指针。
所以是可以进行加法操作的,代表指向位置的移动。
刚开始均有一个p += 2
,也就是指向了第三项a[2]
为$2$。
然后这里打了括号,所以肯定先是运算括号里的东西。
那么p++
和++p
的区别,也就在于是先返回值还是先加一。
- 对于
++p
,先运算,也就指向了a[3]
,再返回值。那么还是$3$。 - 对于
p++
,先返回值,也就是a[2]
,那么a[2]
的值就为$2$了。
故选择C。
设int x[] = {1,2,3,4,5,6}, *p = x;
则数值为$3$的表达式是()。
A. p += 2, *++p
B. p += 2, *p++
C. p += 3, *p
D. p += 2, ++*p
作为之前三道题的汇总练习题。
答案与分析
B. p += 2, *p++
分析
没打括号的时候,*p
最先运算。
A中,*
与p
被++
隔开了,所以只能先运算++p
。
如果换成p += 2, *(p++)
,也是正确答案。
不过其运算过程与B完全不一样,运算后的结果更不一样!
第三十九、四十、四十九、五十题
因为这几道题考点相同,故放在一起形成对照。
设有定义语句:int a[5], *p = a;
,
则下列描述错误的是()。
A. 表达式p = p + 1
是合法的
B. 表达式a = a + 1
是合法的
C. 表达式p - a
是合法的
D. 表达式a + 1
是合法的
答案与分析
B. 表达式a = a + 1
是合法的
分析
需要注意到:数组名其实也是一个指针,代表这个数组的起始位置,相当于&a[0]
。
但其是常量指针,故不可以执行赋值语句。
也就是a + 1
是对的,代表&a[0] + 1
,
a = a + 1
是错的,没法把&a[0] + 1
赋值给&a[0]
。
有下面语句int a[10] = {10,9,8,7,6,5,4,3,2,1}, *p = a
,
则数值为$2$的表达式是()。
A. a[9]
B. *p[8]
C. *(a+8)
D. p+8
个人做错了这道题!
【虽然是我没认真看题错的_(:з」∠)_……
答案与分析
C. *(a+8)
分析
- A、
a[9]
,代表的是数组第十个元素,也就是$1$。 - B、
p[8]
的时候,已经代表的是第九个元素的值了,所以不能再加*
。
也就是说如果选项是p[8]
就是对的,*p[8]
存在语法错误。 - C、
*(a+8)
,也就相当于a[8]
,故为$2$,正确。 - D、
p+8
,代表的是第九个元素的地址,不是里面的值。
也就是说如果选项是*(p+8)
就是对的。
若有定义int a[10], *p = a;
,
对数组元素错误的使用的语句是()。
A. *(a+1)
B. *(p++)
C. p[1]
D. *(a++)
答案与分析
D. *(a++)
分析
跟前两道题一样,关键是多了++
这个自增运算符。
对于B,p
是个指针变量,是可以执行自增(或说赋值)的语句的。
而对于D,p
是个指针常量,是不能执行自增(或说赋值)的语句的。
若有定义int a[] = {0,1,2,3,4,5,6,7,8,9}, *p = a, i;
,
对数组元素正确的使用的语句是()。
A. a[p]
B. p[a]
C. p+12
D. a[p-a]
作为之前三道题的汇总练习题。
答案与分析
D. a[p-a]
分析
注意[]
里面,只能为具体的数值
也就是说A、a[p]
和B、p[a]
均错误,
因为[]
里是地址,而不是数值。
A改为
a[*p]
,则正确,代表a[0]
,
B改为p[*a]
,则正确,代表p[0]
(即a[0]
)。
但如果数组元素换位int a[]={-1,0,1,2,3,4,5,6,7,8}
,
那么即便改为a[*p]
也不正确,因为其代表a[-1]
,对数组元素使用错误。
C是很明显的数组越界。
D中,前面的题(第十题)介绍过,指针间存在减法运算。
那么这道题中p-a
的运算结果为$0$(因为指向同一位置a[0]
,之间不存在距离),
然后a[0]
是正确使用。
第四十三题
设char str[] = "hello", *p = str;
,
则*(p+5)
的值是()。
A. 随机值
B. 字母o
C. 字符串结束标志\0
D. 字母o
内存的地址
答案与分析
C. 字符串结束标志\0
分析
*(p+5)
,也就是从字符串开头往后数$5$位。
会发现,最后只能往后数$4$位到o
,
别忘了在字符数组char []
中,最末尾还会有一个看不见的\0
这个东西,
所以存在*(p+5)
,代表的就是\0
。
第四十六题
设有定义语句int *p[4];
,
则标识符p
是()。
A. 一个指向整型变量的指针变量
B. 一个指向整型的指针数组名
C. 一个指针,它指向一个含有四个整型元素的一维数组
D. 一个非法的定义语句
个人做错了这道题!
【虽然是我没认真看题错的_(:з」∠)_……
答案与分析
B. 一个指向整型的指针数组名
分析
就注意一下这种定义方式,
其类型就是一个指向整型的指针数组名。
第五十一题
若有定义:int a[] = {1,2,3,4,5,6,7,8,9,10}, *p = a;
,
则数值为$7$的表达式为()。
A. *(p+7)
B. p[*(a+6)]
C. p+6
D. a[*(p+5)]
个人做错了这道题!
答案与分析
D. a[*(p+5)]
分析
首先很容易判断出A,其数值为$8$,
C,其没有加*
,故代表的是a[6]
的地址。只有加了*
,即*(p+6)
才数值为$7$。
而B、D,关键要先把[]
内部的给运算出来,
D中,*(p+5)
的值为$6$,而a[6]
的值为$7$,
所以D的最终值为$7$,符合题意。
第五十四题
若有定义:int a[3][4]
,
能正确表示数组a
中元素地址的是()。
A. *(a[1]+4)
B. *(*(a+3)+1)
C. *(a[1]+2)*
D. *(*(a+1)+1)
个人做错了这道题!
为一道很混淆的操作题。
答案与分析
D. *(*(a+1)+1)
分析
个人暂时也不知道原因,正在询问老师【……
觉得C好像也是对的……
没写入的题
以下题均为比较新的概念题,但个人没有写入,还是推荐去看一下记一下。
- 第六题——常量是否能赋给指针
- 第七题——数组名代表数组首地址
- 第四十五题——
int *point = new int(4)
,这段代码的执行顺序