我要努力工作,加油!

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

		发表于: 2018-09-27 17:11:17 | 已被阅读: 34 | 分类于: C语言
		

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;

i
j
是只读的,不能被修改,这是 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
可以随意修改,而它指向的内容却不能修改。对于
c
const
修饰的则是
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