随笔 - 6, 文章 - 0, 评论 - 5, 引用 - 0
数据加载中……

const * * const


1.const int *r=&x; //声明r为一个指向常量的x的指针,r指向的对象不能被修改,但他可以指向任何地址的常量。

先是一个指针 *r,则*r所指的对象不可被修改。

2.int const *r=&x; //与用法1完全等价,没有任何区别。

3.int * const r=&x; //声明r为一个常量指针,他指向x,r这个指针的指向不能被修改,但他指向的地址的内容可以修改。

先是一个常量,则其值不可修改,

4.const int * const r=&x; //综合1、3用法,r是一个指向常量的常量型指针。



原文: http://www.fjtu.com.cn/fjnu/courseware/1308/course/_source/web/lesson/chapter9/j5.htm

第五节  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都是常量,它们都不能作为左值进行操作

posted on 2009-05-06 18:24 qhmao 阅读(674) 评论(4)  编辑 收藏 引用

评论

# re: const * * const  回复  更多评论   

const是C++中引入的一个新的关键字,它为C++编程带来了很大的方便。指向const对象的指针和const指针是两个名字很接近的概念,对于初学者来说非常容易搞混,这里对它们进行区分。
  指向const对象的指针
  可以这样理解指向const对象的指针:
  指向const对象的指针就是一个指针,不能通过它来修改它所指向的对象的值
  · 声明方法:const int *p;
  const对象在初始化后是不允许对其值进行修改的,因此,我们不能用一个普通指针指向一个const对象,即下面的赋值会引起编译错误:
  const int i = 1;
  int *p = &i;
  否则的话,我们就可以利用普通指针来修改一个const对象的值,那么const也就毫无意义了。
  正确的方法是利用一个指向const对象的指针来获取const对象的地址:
  const int i = 1;
  const int *p = &i;
   这样,利用指向const对象的指针也是不能修改它所指向的const对象的值的。
  需要注意的两点:
  指向const对象的指针本身不是const类型(这也是它与const指针的主要不同点),所以它可以指向另一个const对象
  指向const对象的指针可以被赋予一个非const对象的地址,但是此时试图通过此指针来修改对象的值的操作是非法的
  2. const指针
  可以这样理解const指针:
  const指针就是一个指针,它本身就是const类型,所以将它初始化后不能再改变它的指向,即不能让它指向一个新的对象
  声明方法:
  int *const p;//指向非const对象的const指针
  const int *constp;//指向const对象的const指针
  由以上声明方法可以看出,const指针可以指向const对象和非const对象,但是两者的声明方法是不同的。
  使用const指针不可以修改其地址值,但是const指针指向非const对象,就可以利用它修改它所指向的对象的值。
  总结:
  初学者之所以会混淆两者的根本原因是他们头脑中的一些隐式假定在作怪,也就是说想当然地给要分析的对象强加上一些它们原本并不存在的属性,这是很多人在处理问题时很容易犯的一个通病。只要语法规则没有明确说明是非法的,我们就可以拿来用,而没有必要人为地加上种种限制。其实要弄清两者的区别,只要明确两点就够了:
  指针本身是const型还是非const型
  指针所指向的对象是const型还是非const型
  const型变量的值在初始化后是不允许改变的(这是根本),那么const指针其指向是不能变的,const对象其值是不能变的,一切都清楚了
  2.要弄清楚上面的两个问题,有一个很简单的办法:
  如果指针名前紧邻的关键字为const,那么它就是一个const指针;如果声明指针所指向的对象类型前有const关键字,那么它就是一个指向cosnt对象的指针。
  应用上面的判断方法,const int *const p; 就表示指向const对象int的const指针。
2009-05-11 16:36 | qhmao

# re: const * * const  回复  更多评论   

const * 常量指针 const char* source 所指向的对象不可被修改

* const 指针常量 指针常量定义"int *const pc=&b;”告诉编译,pc是常量,不能作为左值进行操作,但是允许修改间接访问值,即*pc可以修改。
2009-05-11 17:06 | qhmao

# re: const * * const  回复  更多评论   

const char* source const 指向最近的那个,,,,,*source不可修改,

char * const pc = &b const指向最近的那个,,,,, pc不可修改
2009-05-11 17:10 | qhmao

# re: const * * const  回复  更多评论   

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

  可以定义一个指向常量的指针常量,它必须在定义时进行初始化。例如:
    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的值,
2009-05-11 17:16 | qhmao

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理