zoukankan      html  css  js  c++  java
  • 指针常量和常量指针的一些整理

    近来学习指针,碰到一个关于指针常量和常量指针的问题,之前被弄得是稀里糊

    涂的,今天特意查资料整理了一下,现拿出来和大家分享,有什么弄错的地方请

    大家不吝赐教,共同进步。

    首先常量指针,咱们可以这样理解,常量指针即是一个指向常量的指针,既然指

    向的是一个常量,那它所指向的值当然就不能变了。但是它本身的值,即它的地

    址是可以变的,咱们可以把它指向别的地址。

    而指针常量,则可以理解为一个常量,什么时候常量??指针常量,即指针是常

    量,则它的地址是不可变的,但是它所指向的地址里的值是可以变的。

    一个int型的常量指针是这样定义的:int const* 指针名。int const(常量)*(

    指针)指针名
    一个int型的指针常量是这样定义的:int* const 指针名。int*(指针) const(常

    量)指针名
    观察上面两个的定义我们是不是可以根据*和const的位置来一眼判断是一个指针

    常量还是一个常量指针呢???*前const后是指针常量,const前*后是常量指针!!

    !呵呵,当然最重要的还是要理解它们所代表的含义,哪个能改,哪个不能!

    现在可以通过下面的一段代码再来看看自们理解的怎么样了。试试看下面的代码

    哪里有问题,为什么!

    #include<stdio.h>
    int main(){
      int i=0;
      int j=1;
      int x;
      const int * pi=&i;
      *pi=22;
      pi=&j;
      int * const pj=&j;
      *pj=22;
      pj=&i;
      const int * px=&x;
      const int h=2;
      const int* ph=&h;
      int* const ph2=&h;
    }

    理解:

    #include<stdio.h>
    int main(){
      int i=0;
      int j=1;
      int x;
      const int * pi=&i;//定义一个常量指针pi,它指向的地址是i
      *pi=22;//有问题了,pi是一个常量指针,它指向的地址的值你竟敢改
      pi=&j;//没问题,pi虽然指向的是一个常量,但本身还是自由的,还是可以改

    变的
      int * const pj=&j;//这里定义一个指针常量,指向的是j的地址。
      *pj=22;//没问题,指针常量只是指针是个常量,地址是常量,但我里面的内容

    可以变啊,好歹也有点自由啊
      pj=&i;//这里就不对了,既然是个常量就乖乖地别换地址
      const int * px=&x;//这里也没问题,可能就有人会有疑问了,你px不是一个

    常量指针吗,你不是说常量指针是一个指向常量的指针吗,x又不是一个常量,杂

    就可以呢?呵呵,这个是我之前有疑问,后来我把px所指向的值输出来,然后再

    试图给px赋值,但不行,x已经被赋上了一个垃圾值。
    所以说的常量指针是一个指向常量的指针这仅仅是便于我们理解,事实上它还是

    可以指向一个变量的,不过一旦定义后该变量也就成了一个不变的量了。
      const int h=2;
      int* const ph2=&h;//有问题,我上面定义了h是一个常量,你怎么可以用一个

    指针变量来指向h呢。若是可以的话,你指针常不是可以修改所指向地址的内容,

    那不意味着可以修改h的值了,可h是个常量,怎么能让你这么做!!!
      const int* ph=&h;//所以还是用常量指针吧,指向的地址的值不变。
    }

    其实我觉得就是中文翻译的比较故弄玄虚。

    你所谓的常量指针,其实英文是 pointer to const,经常翻译成就叫指向常量的指针。其实这么叫就不那么容易混淆。
    另外指针常量,英文是 const pointer,经常也能看见翻译成常指针的,要是这么叫反而感觉容易和上面那个搞混。

    而且有关 constant 这个词,做为术语,有一定的歧义。有的时候,它只包含诸如 1, 1L, "abc", 12.5 'c' 这样的东西。有的时候他也指 const variable。就是指 const int 这类东西,声明一个变量,但看成常量。(常见的是翻译成“常量变量”或者“常变量”,不过按照你的那个命名逻辑应该叫“变量常量”)。而且很多时候在上下文里其实仅指后者,因为前者比较简单,通常不需要考虑。

    后来标准委员会换了一个词,用 literal 来代表 1, 'c' 这样的东西,一般被翻译成“字面”。比如前者叫整形字面,后者叫字符字面。而常量变量就统称为常量,比如 const int a,就说声明了一个整形常量(const integer)。但中文不知道是不是习惯问题,也有把 literal 这个词翻译成 字面常量 的。

    总之翻译还是很混乱的。不过楼主讲的还算清楚,只要别死抠这两个中文术语就行了。

    另外我也看到过另一种记忆的方法:
    const int * const p;
    看成 const int (* const p)。把 * 前的理解成加完 * 之后的东西,括号里的理解成未加星的东西。
    当出现比如 : *p = 5; 这样的语句的时候,由于有星了,那么到括号外头找,左边的东西本质上是 const int。
    而 p = 5; 找括号里面的是 const p,那么这就是给一个常量赋值,也不行。

    这种记法对复杂一点的东西也有用:

    程序代码:
    int f() { return 0; }

    int main()
    {
        int (*p)(void);
        p = &f;

        int a[5];
        int (*q)[5];
        q = &a;

        return 0;
    }

    int (*p)(void)。 p 是一个指针,而 *p 是 int _ (void),所以是个指向函数的指针。
    int (*q)[5]。q 是一个指针,而 *q 是 int [5],所以 q 是个指向 int [5] 这样数组的指针。
    当然不管怎么记,复杂的东西还是会比较复杂。

  • 相关阅读:
    二叉树
    消息
    线性表 及Java实现 顺序表、链表、栈、队列
    Memcache简介
    redis例子
    redis简介
    Android客户端采用Http 协议Post方式请求与服务端进行数据交互(转)
    jQueryValidate实现重复性验证
    mybatis中${}和#{}的区别
    List转换为数组Array的方法
  • 原文地址:https://www.cnblogs.com/aabbcc/p/6025949.html
Copyright © 2011-2022 走看看