在c中使用const关键字

ABH*_* EA 6 c syntax pointers constants declaration

我一直在查看源代码,我遇到了这段代码

    static char const *const delimit_method_string[] =
    {
        "none", "prepend", "separate", NULL
    };
Run Code Online (Sandbox Code Playgroud)

我以为我知道Cconst语言中关键字的含义,但是看到这个语法后我很困惑,因为我无法解码语法的含义,所以我想知道这样使用的含义我在网上搜索了一些问题就像 stackoverflow 中的这样,const

  1. C/C++签名中两个const的含义
  2. 双常量声明

但我仍然不明白该代码片段中语法的含义是什么,可能是因为我对C的基础知识不够好,但我真的很想改进它。

所以我写了一些代码来了解该语法是如何工作的,这就是我尝试过的:

    #include <stdio.h>
    
    int main()
    {
        char a = 'A';
        char b = 'B';
        char const * const ptr = &a;

        ptr = &b;

        printf("a is %c\n", *ptr);
        printf("a is %c", a);
    
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

我得到了这个输出,这在某种程度上是我所期望的。

$ gcc test.c
test.c: In function 'main':
test.c:9:13: error: assignment of read-only variable 'ptr'
    9 |         ptr = &b;
      |  

                    ^
Run Code Online (Sandbox Code Playgroud)

我修改了代码并再次测试,

    #include <stdio.h>
    
    int main()
    {
        char a = 'A';
        char b = 'B';
        char const const *ptr = &a;
    
        ptr = &b;

        printf("a is %c\n", *ptr);
        printf("a is %c", a);
    
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

这次的输出不是我预期的,

$ ./a.exe
a is B
a is A
Run Code Online (Sandbox Code Playgroud)

如果有人能解释Cconst中的正确使用方法以及第一个代码片段中的语法如何工作,我真的很感激。

Vla*_*cow 4

本声明

static char const *const delimit_method_string[] =
{
  "none", "prepend", "separate", NULL
};
Run Code Online (Sandbox Code Playgroud)

声明一个数组,其名称delimit_method_string为指向字符串文字的指针。

在 C 中,与 C++ 相反,字符串文字具有非常量字符数组类型。尽管如此,您不能更改字符串文字。任何更改字符串文字的尝试都会导致未定义的行为。因此,最好按以下方式声明指向字符串文字的指针,例如

const char *s = "Hello";
Run Code Online (Sandbox Code Playgroud)

所以你可以像这样声明上面的数组

static char const * delimit_method_string[] =
{
  "none", "prepend", "separate", NULL
};
Run Code Online (Sandbox Code Playgroud)

但是声明这个数组的程序员也想将 at 声明为常量数组。那就是他希望它的元素不能被改变。

对于上面的声明你可以写例如

delimit_method_string[0] = "all";
Run Code Online (Sandbox Code Playgroud)

为了防止这种变化,数组的元素必须是常量。为此,您需要编写

static char const * const delimit_method_string[] =
{
  "none", "prepend", "separate", NULL
};
Run Code Online (Sandbox Code Playgroud)

const char *现在,由于第二个限定符 const,具有指针类型的数组元素是常量。

考虑以下声明,汤姆会更清楚地说明这一点。

char *p;
Run Code Online (Sandbox Code Playgroud)

该声明声明了一个指向 类型的非常量对象的非常量指针char

const char *p;
Run Code Online (Sandbox Code Playgroud)

该声明声明了一个指向 类型的常量对象的非常量指针char

const char * const p;
Run Code Online (Sandbox Code Playgroud)

该声明声明了一个指向 类型的常量对象的常量指针char

最后的声明可以重写为

const char ( * const p );
Run Code Online (Sandbox Code Playgroud)

至于你的声明

char const const *ptr = &a;
Run Code Online (Sandbox Code Playgroud)

那么两个限定符中的一个const是多余的,因为它们都引用类型说明符char