`
ruilin521314
  • 浏览: 884306 次
文章分类
社区版块
存档分类
最新评论

const 指针

 
阅读更多

第五节  const 指针

  对于下面涉及指针定义和操作的语句:
    int a=1;
    int *pi;
    pi=&a;
    *pi=58;

  可以看到,一个指针涉及到两个变量,指针本身pi和指向的变量a。修改这两个变量的对应操作为“pi=&a;”和“*pi=58;”。

1.指向常量的指针(常量指针)


  在指针定义语句的类型前加const,表示指向的对象是常量例如:
    const int a=78;
    const int b=28;
    int c=18;
    const int*pi=&a; //指针类型前力口const
    *pi=58; //error:不能修改指针指向的常量
    pi=&b; //ok:指针值可以修改
    *pi=68; //error:同上
    pi=&c;
    *pi=88; //error:同上
    c=98; //ok

  a是常量,将a的地址赋给指向常量的指针pi, 使a的常量性有了保证。如果企图修改a,则会引起“不能修改常量对象”(Cannot modify a const object)的编译错误。
  可以将另一个常量地址赋给指针“pi=&b;” (指针值可以修改),这时,仍不能进行“*p =68;”的赋值操作,从而保护了被指向的常量不被修改。 见图8-4,图中阴影部分表示不能


图8-4 指向常量的指针

  被修改。可以将一个变量地址赋给指针“pi=&c;”, 这时,由于不能进行“*pi=88;”的赋值操作,从而保护了被指向的变量在指针操作中不被修改。定义指向常量的指针只限制指针的间接访问操作,而不能规定指针指向的值本身的操作规定性。例如,变量c可以修改,这在 函数传递中经常被使用。
  例如,下面的程序将两个一样大小的数组传递给一个函数,让其完成复制字符串的工作,为了防止作为源数据的数组遭到破坏,声明该形参为常量字符串:
    
//**********************
    //**   ch8_10.cpp  **
    //**********************

    #include <iostream.h>

    void mystrcpy(char* dest, const char* source)
    {
     while(*dest++ = *source++);
    }

    void main()
    {
     char a[20]="How are you!";
     char b[20];
     mystrcpy(b,a);
     cout <<b <<endl;
    }

  运行结果为:
    How are you!

  变量字符串a传递给函数mystrcpy()中的source, 使之成为常量,不允许进行任何修改、但在主函数中, a却是一个普通数组,没有任何约束,可以被修改。
  由于数组a不能直接赋值给b, 所以通过一个函数实现将数组a的内容复制给数组b。
  函数mystrcpy()中的语句是一个空循环,条件表达式是一个赋值语句。随着一个赋值动作,便将一个a数组中的字符赋给了b数组中对应的元素,同时两个数组参数都进行增量操作以指向下一个元素。只要所赋的字符值不是'/0',(条件表达式取假值),则循环就一直进行下去。 ,
  常量指针定义"const int *pi=&a;”告诉编译,*pi是常量,不能将,pi作为左值进行操作。

2.指针常量


  在指针定义语句的指针名前加const,表示指针本身是常量例如:
    char *constpc="asdf"; //指针名前加const定义指针常量
    pc="dfgh"; //error:指针常量不能改变其指针值
    *pc='b'; //ok:pc内容为,'bsdf',
    *(pc+1)='c'; //ok:pc内容为'bcdf',
    *pc++='y'; //error:指针常量不能改变其指针值
    const int b=28;
    int* const pi=&b; //error:不能将const int*转换成int*

  pc是指针常量,在定义指针常量时必须初始化,就像常量初始化一样。这里初始化的 值是字符串常量的地址,见图8_5


图8_5 指向变量的指针常量图

  由于pc是指针常量,所以不能修改该指针值。“pc="dfgh";”将引起一个“不能修改常量对象”(Cannot modify a const object)的编译错误。
  pc所指向的地址中存放的值并不受指针常量的约束,即*pc不是常量,所以“*pc='b';”和“*(pc+1)='c';”的赋值操作是允许的。但“*pc++=y;”是不允许的,因为该语句修改*pc的同时也修改了指针值。
  由于此处*pi是不受约束的,所以,将一个常量的地址赋给该指针“int* const pi=&b;”是非法的,它将导致一个不能将const int *转换成int *的编译错误,因为那样将使修改常量(如:“* pi=38;”)合法化。
  指针常量定义"int *const pc=&b;”告诉编译,pc是常量,不能作为左值进行操作,但是允许修改间接访问值,即*pc可以修改。

3.指向常量的指针常量(常量指针常量)


  可以定义一个指向常量的指针常量,它必须在定义时进行初始化。例如:
    const int c=7;
    int ai;
    const in * const cpc=&ci; //指向常量的指针常量
    const int * const cpi=&ai; //ok
    cpi=&ci; //error:指针值不能修改
    *cpi=39; //error:不能修改所指向的对象
    ai=39; //ok

  cpc和cpi都是指向常量的指针常量,它们既不允许修改指针值,也不允许修改*cpc的值,见图8-6。


图8—6 指向常量的指针常量

  如果初始化的值是变量地址(如&ai), 那么不能通过该指针来修改该变量的值。也即“*cpi=39;”是错误的,将引起“不能修改常量对象”(Cannot modify a const object)的编译错误。但“ai=39;”是合法的。
  常量指针常量定义“coastint * coastcpc=&b;”告诉编译,cpc和* cpc都是常量,它们都不能作为左值进行操作。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics