那些走过的坑

const char *p和char * const p那些事

看了一些关于const的文章,趁还记得,赶紧把它写下来。

首先看看下面这些声明:

[v_notice]

const char *p;   //p is a pointer point to const char

char const *p;  //p is a pointer point to const char

char* const p;  //p is a const pointer point to char

const char* const p; //p is a const pointer point to const char

char const* const p;  //p is a const pointer point to const char

[/v_notice]

是不是有点晕?

上面的声明有一种好记的方法就是从右往左读,比如说const char *p,可以读成“p is a pointer point to const char”,实际上const只修饰它左边的类型,只有当const左边没有内容时才修饰它右边的类型,所以

const char *p 和char const *p效果是一样的。

下面有个题:

[v_tips]

给出以下定义,下列哪些操作是合法的?

const char *p1 = “hello”;

char * const p2 = “world”;

A.p1++;

B.p1[2] = ‘w’;

C.p2[2] = ‘1’;

D.p2++;

[/v_tips]

初看上去,是一脸懵逼的,那就敲一遍,看看哪个是正确的。

#include<stdio.h>
int main(){
    const char *p1 = "hello";  //(1)
    char *const p2 = "world";  //(2)

    p1++;  //(A)
    p1[2] = 'w';  //(B) error: assignment of read-only location '*(p1 + 2u)'
    p2[2] = '1';  //(C) error: increment of read-only variable 'p2'
    p2++;  //(D) error: increment of read-only variable 'p2'
    printf("%s\n", p1);  //输出:ello
}

可以看出,只有A是正确的,但是为什么呢?

  1. 语句(1)定义了一个指向字符常量的指针变量p1;
  2. p1中存储的是字符串“hello”的首地址,即“h”的地址;
  3. 假设字符串“hello”的首地址为x,那么p1中存储的就是地址x;
  4. 由于const修饰char,所以char是不可改变的,也就是地址x中的内容不可改变。

所以可以改变p1的指向,即p1可以指向其他字符,譬如可以使:p1 = “hehe”;

但不能通过p1修改地址为x的这块内容。

  1. 语句(2)定义了一个指向字符的指针常量p2;
  2. p2中存储的是字符串“world”的首地址,即“w”的地址;
  3. 假设字符串“world”的首地址为a,那么p2中存储的就是地址a;
  4. 由于const修饰指针p2,所以p2是不可改变的,也就是p2的指向不可改变。

所以可以改变p2所指向的字符的值,但不能改变p2的指向。也就是p2中只能存储地址a,但地址a中字符的值可以修改。

下面再看选项:

  • p1++;  修改了变量p1的指向,使得变量移动1,指向了’e’,正确。
  • p1[2] = ‘w’;  试图修改字符串常量的值,错误。
  • p2[2] = ‘1’;  试图修改字符串常量的值,错误。
  • p2++;  试图修改变量p2的指向,错误。

这里特别指出:

内存中开辟了一个字符数组用于存储字符串常量“hello”,这段常量字符串是存储在静态存储区的,内容不能修改,也就是其中的任何一个字符都不可修改。p1[2] = ‘w’和p2[2] = ‘1’,都试图修改字符串中的第三个字符的值,所以是错误的。

再看看下面的声明:

const char* const p; //p is a const pointer point to const char

char const* const p;  //p is a const pointer point to const char

事实上若声明时一并初始化了,那么这两句和char * const p;是等价的,因为指针变量指向的字符串都不可改变,指针的指向也不可改变。

 

以上纯属本人个人研究所得,如有不对之处,请指正。

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注