C语言const的使用,const修饰指针时,const char*,char const*和char* const有什么区别?

c语言的const关键字用于声明(定义)只读变量,可用于保护某些变量的内容在使用中不会被更改。const关键字使用非常简单,在类型声明符前,或者后都是可以的,二者是等价的。例如下面这个 demo:

#include <stdio.h>

int main()
{
    const char i = 3;
    char const j = 13;      // const char 和 char const 是等价的
    i = 4;
    j = 14;
    return 0;
}

编译会报错:

$ gcc t.c
t.c: In function ‘main’:
t.c:27:7: error: assignment of read-only variable ‘i’
     i = 4;
       ^
t.c:28:7: error: assignment of read-only variable ‘j’
     j = 14;

ij是只读的,不能被修改,这是 c 语言语法限制的。

const 修饰指针

上面的demo很简单,这里我们再来看看复杂点的情况:const修饰指针。以 char 类型指针为例,使用const有 3 种写法:

  1. const char*
  2. char const*
  3. char* const

先只看 char*,我们知道这是一个char类型的指针,char是修饰*的。而 const 放在类型声明符前后都是等价的,因此上面的第一种第二种写法是等价的。

现在再来分析const关键字在指针声明中的作用。其实就一句话:const靠近谁,就修饰谁。例如:

char a[9] = {0};
char const* b = a;
char* const c = a+1;

对于指针变量b,因为const修饰的是*,所以*b是只读的,b可以随意修改,而它指向的内容却不能修改。对于cconst修饰的则是c本身,所以c是只读的,c不能被修改,但是它指向的内容却可以被修改。

下面写个小 demo 做试验:

#include <stdio.h>

int main()
{
    char buf[128] = {0};

    const char* test1 = buf;
    char const* test2 = buf+1;
    char* const test3 = buf+2;

    printf("%p, %p, %p\n", test1, test2, test3);

    test1 = buf+3;
    test2 = buf+4;
    test3 = buf+5;

    printf("%p, %p, %p\n", test1, test2, test3);

    *test1 = 101;
    *test2 = 102;
    *test3 = 103;

    printf("%d, %d, %d\n", *test1, *test2, *test3);

    return 0;
}

我们编译,发现报错:

$ gcc t.c
t.c: In function ‘main’:
t.c:15:11: error: assignment of read-only variable ‘test3’
     test3 = buf+5;
           ^
t.c:19:12: error: assignment of read-only location ‘*test1’
     *test1 = 101;
            ^
t.c:20:12: error: assignment of read-only location ‘*test2’
     *test2 = 102;

注释 15, 19, 20 行,

...
    //test3 = buf+5;

    printf("%p, %p, %p\n", test1, test2, test3);

    //*test1 = 101;
    //*test2 = 102;
...

再编译就成功了,执行之,输出与预期一致。

$ gcc t.c 
$ ./a.out 
0x7fff85a12620, 0x7fff85a12621, 0x7fff85a12622
0x7fff85a12623, 0x7fff85a12624, 0x7fff85a12622
0, 0, 103
阅读更多:   C语言 , Linux笔记
添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gif