在 c 中使用 const 关键字
Using const keyword in c
我一直在看源代码,我偶然发现了这段代码
static char const *const delimit_method_string[] =
{
"none", "prepend", "separate", NULL
};
我以为我知道 C 语言中 const
关键字的含义,但是看到这个语法后我感到困惑,因为我无法解码语法,所以我想知道像这样使用 const
的含义 我在互联网上搜索 我在 Whosebug 中看到了一些这样的问题,即
- Meaning of two const in C/C++ signature
- Double const declaration
但我仍然不明白该代码片段中语法的含义,可能是因为我对 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
的正确方法以及第一个代码片段中的语法是如何工作的,我将非常感激。
char const const *ptr = &a;
这个双 const
没有任何特殊意义,因为它们都在 *
的同一侧。额外的 const
限定符被编译器忽略。可以这样写 char const const const const const*ptr = &a;
和 char const *ptr = &a; 是一样的这意味着:
pointer to constant character
如果我们把它改成
char const * const ptr = &a;
这意味着:
constant pointer to constant char
您的代码段将停止编译: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
顺便说一句,我个人更喜欢在类型之前有第一个常量,即:
static const volatile char *const delimit_method_string[]
const char *p
这个声明
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
.
我一直在看源代码,我偶然发现了这段代码
static char const *const delimit_method_string[] =
{
"none", "prepend", "separate", NULL
};
我以为我知道 C 语言中 const
关键字的含义,但是看到这个语法后我感到困惑,因为我无法解码语法,所以我想知道像这样使用 const
的含义 我在互联网上搜索 我在 Whosebug 中看到了一些这样的问题,即
- Meaning of two const in C/C++ signature
- Double const declaration
但我仍然不明白该代码片段中语法的含义,可能是因为我对 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
的正确方法以及第一个代码片段中的语法是如何工作的,我将非常感激。
char const const *ptr = &a;
这个双 const
没有任何特殊意义,因为它们都在 *
的同一侧。额外的 const
限定符被编译器忽略。可以这样写 char const const const const const*ptr = &a;
和 char const *ptr = &a; 是一样的这意味着:
pointer to constant character
如果我们把它改成
char const * const ptr = &a;
这意味着:
constant pointer to constant char
您的代码段将停止编译: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
顺便说一句,我个人更喜欢在类型之前有第一个常量,即:
static const volatile char *const delimit_method_string[]
const char *p
这个声明
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
.