首页 > 试题广场 >

给定声明 const char * const * pp;

[单选题]
给定声明 const char * const * pp; 下列操作或说明正确的是?
  • pp++
  • (*pp)++
  • (**pp) = 0;
  • 以上都不对
推荐
【正确答案】A
【解析】const 限定一个数据为只读属性。
1.const char p; 限定变量 p 为只读。
2.const char *p; p 为一个指向 char 类型的指针,const 限定 p 指向的数据为只读。所以 *p 的值不能被修改,而指针变量 p 本身的值可以被修改。
3.char * const p; 限定此指针变量为只读,所以 p 的值不能被修改,而 *p 的值可以被修改。
4.const char *const p; 两者皆限定为只读,不能修改。
对比以上,二级指针如下:
1.const char **p; p为一个指向指针的指针,const 限定其最终数据为只读,所以 **p 不能修改,而 p 的值本身可以修改。
2.const char * const *p; 限定二级指针指向的数据和 p 指向的指针为只读。所以 **p 的值不能修改,*p 的值也不能修改。
3.const char * const * const p 全部限定为只读,都不被修改。

const 和指针知识点讲解】
更多C++基础专业知识讲解,点击链接即可查看
https://www.nowcoder.com/link/zxyl-cpp09
编辑于 2021-11-17 14:53:10 回复(0)
mlc头像 mlc
const 限定一个对象为只读属性。
先从一级指针说起吧:
(1)const char p    限定变量p为只读。这样如p=2这样的赋值操作就是错误的。
(2)const char *p   p为一个指向char类型的指针,const只限定p指向的对象为只读。这样,p=&a或  p++等操作都是合法的,但如*p=4这样的操作就错了,因为企图改写这个已经被限定为只读属性的对象。
(3)char *const p  限定此指针为只读,这样p=&a或  p++等操作都是不合法的。而*p=3这样的操作合法,因为并没有限定其最终对象为只读。
(4)const char *const p 两者皆限定为只读,不能改写。
有了以上的对比,再来看二级指针问题:
(1)const char **p  p为一个指向指针的指针,const限定其最终对象为只读,显然这最终对象也是为char类型的变量。故像**p=3这样的赋值是错误的,而像*p=? p++这样的操作合法。
(2)const char * const *p 限定最终对象和 p指向的指针为只读。这样 *p=?的操作也是错的。
(3)const char * const * const p 全部限定为只读,都不可以改写。
发表于 2015-04-14 20:16:43 回复(38)

看const后面是什么类型,所以第一个const确保*p不会被修改,第二个const确保p不会被修改,pp没有const限制,所以就选A了。

发表于 2017-09-01 17:40:25 回复(0)
A
【解析】
相当于
(char const) (* const) *pp
所以
**p是char型常量
*p是char const *型常量
p是char const *const型变量
编辑于 2021-11-17 14:53:10 回复(6)
我选A(注:如果答案不是A,请忽略下面的分析)
分析:
分析的原则(个人总结):
若const限定符在*之前,则const限定的是*ptr而不限定ptr。也就是说,ptr可以改变其所指向的对象,但不能通过该指针修改其所指向对象的值。

若const限定符在*之后,则const限定的是ptr而不限定*ptr。也就是说,ptr不可以改变其所指向的对象,但能通过该指针修改其所指向对象的值。

若在*之前有const限定符且在*之后也有const限定符,则ptr与*ptr都被限定。也就是说,ptr既不可以改变其所指向的对象,也不能通过该指针修改其所指向对象的值。
具体的分析过程:
第一个const限定符位于第一个*操作符之前,所以第一个const限定符对**pp进行限定。也就是说,不能通过该指针去修改其所指向对象指向对象的值。 话有点绕,不妨举个例子:已知有三个节点分别为n1,n2,n3且n1指向n2, n2指向n3,则不能通过n1修改n3的值。
第二个const限定符位于第二个*操作符之前,所以 第二个const限定符对*pp进行限定。
综上,只有pp没有被限定。所以可以通过该指针改变其指向的对象。
发表于 2015-11-10 16:31:04 回复(1)
pp is a pointer to const pointer to const char.
发表于 2017-04-03 15:34:40 回复(1)
可以理解为 观察每个const在* 的哪边,  const在*的左边表示指针里面存着的这个变量地址所保存的不能改变  即 const char* p, char const *p 都表示为 *p 无法进行改变 例如(*p) = 0; 是非法的。    const在*的右边表示这个指针变量值(指向)无法修改,char* const p; 表示p的指向无法改变例如 p++, p=&a; 等操作都是非法的

题中有两个*  先看第一个const位于第一个*的左边 第二个const位于第二个*的左边  可同样的换个写法,保持那个位置关系都是可以的,可以写成: char const * const *pp ,   你可以理解为左边起第一个const是用来限定第一个*的。第二个同理, 上面说了(const在*的左边表示指针里面存着的这个变量地址所保存的不能改变 ) 先看一个*操作符表示  *pp  表示对二级指针取值,取到的是一个一级指针的地址,即这个变量地址是一级指针的地址,这个一级指针不能指向其他地方,(*pp)++ 这样的操作就是非法的。 再看第二个const和*的位置关系也是const在*的左边,即 **pp  里面保存着的这个char变量不能改变  即 (**pp) = 'A'; 这样的操作是非法的。  const并没有在第二个*的右边,所以这个二级指针变量指向是可以改变的  pp++ 等操作都是合法的
发表于 2017-09-10 12:50:53 回复(0)
这种题目一般都从右往左分析。pp左边第一个是“*”,代表pp是一个指针,再左边为“const”,代表pp指向的是一个常量对象,再左边是一个“*”,代表这个常量对象类型为指针,再左边为“const char”,代表这个常量指针指向的对象类型为const char。所以,总的来说,PP是一个指针,指向一个常量指针,而这个常量指针又指向一个常量字符对象。A选项,pp++,因为pp就是一个普通指针,所以可以++;B选项,对pp解引用得到的是一个常量指针,所以不能++,错误;C选项,对pp两次解引用得到的是const char类型,不能对它赋值,错误,所以,综上所述,选A。
发表于 2021-10-20 13:54:37 回复(0)
二级指针,*p不能变,**p不能变
发表于 2017-01-04 09:43:39 回复(0)
const char* const *pp可以知道pp是一个指针,指向一个const char* const类型的对象,不妨记为p,即const char* const p;则p是一个指针常量,即指向不能改,即p只能指向一个const char类型的对象ch,且不能通过*p来改变ch的内容。但是pp却可以改变指向。因此pp++正确。
编辑于 2016-10-13 21:55:43 回复(0)
此处可将 *pp看作s
则const char* const s;常指针常量 俗称常指针
const char* s 常量指针 本质上是一个指针 其所指向地址的内容不可修改 但是地址可以修改
char* const s 指针常量 本质上是一个常量 其所指向的地址不可修改 可是地址所指向的值可以修改

而s的地址则是*pp也就是指针变量本身                      **pp则是s(*pp)所指向地址的值
所以*pp 和 **pp都不可对其进行修改 但是可以对pp进行修改
发表于 2018-11-16 18:02:20 回复(0)
首先明白两点:一:const修饰变量,使变量限制为常量,不能被修改,放在变量前面
二:指针变量也是一种变量,只是存放的是另一个变量的地址,也就是说指针的解引用完全可以用一个假设的变量名代替;比如说  char **p 假设将(**p)=&a; (*p)=&b,也就是p先指向b,b再指向a。
然后看这个题const char * const *pp;  我们假设 (*pp)=&a,也就是说变量pp先指向a,则const放在a前边修饰的是a,所以a是常量,所以(*pp)++也就是a++是错误的;
然后在看二级指针指向的变量为b,即 (char **pp)=b;也就是(*a)=&b;同样
const放在变量b之前,则变量b是常量,不能被修改,所以(**pp)++即b++是错误的。
然后在看指针变量pp本身 没有被const修饰,不是常量,可以被修改 pp++是可以的

const是修饰变量 ,和*符号没有多大关系 ,只要明确 const放在哪个变量之前就好,不管变量是一个常规变量还是一个指针变量。


编辑于 2018-07-13 10:33:23 回复(1)
总结了一个小规律,不知道对不对,大家看看,为节约时间,直接看例子吧
 ***** const ***p,***p不能移动
***** const * const **p,***p和**p都不能移动
**const *** const * const **p,******p、 ***p和**p都不能移动
总之,每一个const后面的东西都是不能移动的,而其他的都可以

发表于 2016-08-25 09:30:48 回复(1)
const始终修饰的右边变量。
const char p 。const修饰的是char,因此p是const常量,不能修改;
const char *p。const修饰的是char,因此p可以修改,但是*p不能修改;
char *const p 。const修饰的是p,p是char*,因此指针p不可以修改;*p可以修改。
const char *const p 。const修饰的char,第二个const修饰的p。那么指针p不能修改;*p也不能修改。
const char * const * pp。const修饰的是char。第二个const修饰的是*。那么p可以修改,*p不可以修改;**p不可以修改
编辑于 2023-11-23 21:03:37 回复(0)
理解含有const的指针时,先把*ptr看作整体,然后再看是否有const限定ptr
发表于 2024-05-19 06:58:49 回复(0)
注意这是二级指针,const后有什么值,什么就不能修改。
发表于 2023-10-16 22:24:27 回复(0)
const char* const* pp 表示一个指向常量指针的指针,即 pp 是一个指针,指向一个常量指针。
这种类型的指针常用于指向字符串数组或二维数组,可以确保数组内容不被修改。  
在上面的例子中,pp 指向 arr 数组的第一个元素,即指向字符串 "Beijing" 的指针。
由于 pp 是一个指向常量指针的指针,因此不能通过 pp 修改指针所指向的字符串,
但可以通过 pp 修改指针本身的值,使其指向数组中的其他元素。




发表于 2023-04-18 10:39:36 回复(0)
遇到复杂类型时从右往左看,首先pp左边是*,说明它是一个普通指针,可以改变它所指的地址,也可以改变它所指地址上的值。 接着把*pp当做一个变量,来看看pp到底指向了个啥,左边第一个类型是const,那就相当于const p,说明pp指向的是一个常量,那么一开始分析的pp可以修改它所指地址上的值就不允许了,也就是还可以pp++,但是(*pp)++就不行了 再把const * pp当成一个整体,接着往左看,发现pp所指的常量是一个指向const char的指针,也就是不允许(**pp)=0 综上选A
发表于 2022-06-23 13:18:18 回复(0)
第一个const右边是**p,因此它绑定**p,**p不可修改。c错。
第二个const右边是*p,因此它绑定*p,*p不可修改。b错。
故选a。
发表于 2020-07-26 20:37:19 回复(0)
个人拙见
看这种东西,两步:
1、
    首先看声明的类型比如char,若char左边有const,则表示右边最后指向的内存区域一定是只读的,比如:
const char a
const char *p1
const char **p2
    a,一块只读的内存,p1,p2最终也都是指向只读的一块内存。
2、
    再看char右边,char右边的const只与指针相关
const char **const p2
const char *const *p3
const char *const * const p4
       char右边有两个*,说明p2,p3,p4是二级指针,右边套娃就ok了,const修饰p2,则p2不可以修改,const修饰 *p3,则*p3,也就是一级指针不可以修改。这就像填空题一样,每一个*号后面都有一个空格你可以往里面填const。

发表于 2020-03-02 15:25:10 回复(0)
**p不可以变  *p不可以变  p可以变😁
发表于 2019-12-26 15:46:50 回复(0)