【问题标题】:Using const keyword in c在 c 中使用 const 关键字
【发布时间】:2022-01-05 00:50:55
【问题描述】:

我一直在看源代码,我偶然发现了这段代码

    static char const *const delimit_method_string[] =
    {
        "none", "prepend", "separate", NULL
    };

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

  1. Meaning of two const in C/C++ signature
  2. Double const declaration

但我仍然不明白该代码sn-p中的语法是什么意思,可能是因为我对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;
    }

我得到了这个输出,有点出乎我的意料。

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

                    ^

我改了代码又测试了,

    #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;
    }

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

$ ./a.exe
a is B
a is A

如果有人能解释在 C 中使用const 的正确方法以及第一个代码 sn-p 中的语法如何工作,我真的很感激。

【问题讨论】:

  • 你对第二个 sn-p 有什么期待?
  • @tstanisl 我以为我会像以前一样收到错误,但我没有收到任何错误
  • 我发现我的 2 美分不足以得到答案,但我总是尝试向后阅读声明:所以 static char const *const delimit_method_string: delimit_method_stringconst 指针 * 指向到const((不可修改)char,即static。这有助于我理解它。
  • @DavidTóth 是的,这是有道理的,谢谢你的把戏:)

标签: c pointers syntax constants declaration


【解决方案1】:
char const const *ptr = &a;

这个双重const 没有任何特殊含义,因为两者都在* 的同一侧。编译器会忽略其他 const 限定符。可以写char const const const const const*ptr = &amp;a; 和 char const *ptr = &a; 一样这意味着:

pointer to constant character

如果我们把它改成

char const * const ptr = &a;

意思是:

constant pointer to constant char

您的 sn-p 将停止编译:https://godbolt.org/z/sM9qnv8fq

例子:

  • const int *ptr; - 指向常量整数的指针
  • int * const ptr; - 指向整数的常量指针
  • const int * const ptr; - 指向常量整数的常量指针

您的第一个示例 static char const *const delimit_method_string[] 声明:

static array of constant pointers to constant character

顺便说一句,我个人更喜欢在类型 ie 之前使用第一个 const:

static const volatile char *const delimit_method_string[]

const char *p

【讨论】:

    【解决方案2】:

    此声明

    static char const *const delimit_method_string[] =
    {
      "none", "prepend", "separate", NULL
    };
    

    声明一个名称为 delimit_method_string 的数组,其中包含指向字符串字面量的指针。

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

    const char *s = "Hello";
    

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

    static char const * delimit_method_string[] =
    {
      "none", "prepend", "separate", NULL
    };
    

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

    上面的声明可以写成例子

    delimit_method_string[0] = "all";
    

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

    static char const * const delimit_method_string[] =
    {
      "none", "prepend", "separate", NULL
    };
    

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

    Tom 更清楚地考虑以下声明。

    char *p;
    

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

    const char *p;
    

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

    const char * const p;
    

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

    最后的声明可以改写为

    const char ( * const p );
    

    至于你的声明

    char const const *ptr = &a;
    

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

    【讨论】:

    • 很好的解释!您可以添加staticconstchar 可以以任何顺序出现在* 之前,含义相同。 static const char *pstatic char const *p 是等价的,还有char const static *p,这很令人困惑:)
    猜你喜欢
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 2013-01-02
    • 1970-01-01
    相关资源
    最近更新 更多