函数工作正常没有“const”标志。 “const”的重要性?

时间:2017-06-30 07:10:42

标签: c const

以下功能使用const char *s1

该功能的作用可能并不重要。如果是字符串,则返回1 包含允许的字符以外的字符。如果它返回0 没有。

int TEST (const char *s1);

int TEST (const char *s1) {
    char * s2= "o123";
    return s1[ strspn(s1, s2) ] != '\0';
} 

如果我要从中移除const部分,该函数似乎工作正常。

为什么我在该函数中需要const术语,如果它没有它可以正常工作?它的重要性是什么?

的含义是什么?
  • 使用?
  • 没有使用?

4 个答案:

答案 0 :(得分:3)

当你有const char *s1时,你告诉编译器你不会修改s1指向的内存的内容。它是编译器的语义信号,因此您不会在函数中出错(尝试更改内容将导致错误)。它还可能允许编译器添加一些优化。

但更重要的是,它是其他程序员阅读代码和使用您的函数的信号。对于“其他程序员”,我还会在几周,几个月或几年内包含,当你回到代码并忘记了它的细节时。

答案 1 :(得分:2)

  

“const”的重要性?

3个理由:

实用性
代码正确性
速度

考虑允许调用代码执行的操作

int TEST_with_const(const char *s1);
int TEST_without_const(char *s1);

char *cs;
const char *ccs
...
TEST_with_const(cs); // allowed
TEST_with_const(ccs); // allowed
TEST_without_const(cs); // allowed
TEST_without_const(ccs); // fails to compile.

最后一个失败是因为TEST_without_const(char *s1);告诉外面的世界,我想要一个指向我可能改变的内存的指针。 ccs不是指向可修改内存的指针。

假设TEST_without_const(char *s1);具有相同的int TEST (const char *s1)主体,则它不需要指向可修改内存的指针

通过使用const char *s1,函数的主体会在编译期间抱怨,如果尝试修改s1指向的内存。如果函数设计不需要修改s1指向的内存,则此检查有助于确保正确性。

根据编译器的不同,const char *可以进行一些优化,但char *不能进行优化。

答案 2 :(得分:1)

此函数中的

const会阻止您在变量指向的内存中写入内容。

在这里,您只检查值是否等于\0并且它是正常的,因为您只读取操作。

int TEST (const char *s1) {
    char * s2= "o123";
    return s1[ strspn(s1, s2) ] != '\0';
} 

如果你这样做,试着写一下s1指针:

int TEST (const char *s1) {
    char * s2= "o123";
    s1[0] = '4'; //Error, s1 is const pointer, can't write to memory pointed to by s1
    return s1[ strspn(s1, s2) ] != '\0';
} 
你的情况下的

const指针意味着这个函数should not将任何数据写入输入指针,只能执行读操作。实际上,您可以更改s1点的位置,但不允许通过s1写入内存。这是为了防止任何错误现在意外写入,因为它可能在某些情况下导致未定义的行为。

答案 3 :(得分:1)

使用const会阻止您或其他人使用您的代码做出意外错误的事情。此外,它是出于文档目的,因为代码的读者知道这些函数不会改变指针所指向的字符(只读)。

此外,如果您使用const正确性,编译器可能会优化您的代码,因为它知道这些值在只读函数内部没有变化。但记录和使您的功能更安全的第一个原因更重要。

您总会遇到三种形式:char* s1const char* s1const char* const s1。第四个但很少需要的形式是:char* const。含义如下:

<强> 1。 char* s1

在这种情况下,s1只是指针一个或多个字符的内存。 以下内容可以/不能在函数内部完成:

/* Function might changes content of s1 */
int TEST (char* s1)
{
   s1[0] = 'A'; /* works */
   *s1 = 'A';   /* same as above works */
   ++s1;        /* this works because the copy of the pointer is non constant */
   ...
}

可以/不能进行以下调用:

char*       str;
const char* const_str;
...
TEST(str);       /* works as str as no restrictions */
TEST(const_str); /* fails because function might change const const_str */

<强> 2。 const char* s1

术语:const char* s1表示s1指针一个或多个字符的内存,无法使用此指针进行更改 。以下内容可以/不能在函数内部完成:

/* Function is read-only and doesn't changes content of s1 */
int CONST_TEST (const char* s1)
{
   s1[0] = 'A'; /* compiler fail */
   *s1 = 'A';   /* same as above compiler fail */
   ++s1;        /* this works because the copy of the pointer is non constant */
   ...
}

可以/不能进行以下调用:

char*       str;
const char* const_str;
...
CONST_TEST(str);       /* works as str as no restrictions */
CONST_TEST(const_str); /* works because function is read-only and const_str is it also */

编译器将无法编译并告诉您尝试写入标记为常量的内存位置。

第3。 const char* const s1

这意味着:s1是一个常量指针一个或多个字符的内存,无法使用此指针进行更改。这是第一种方法的扩展,指针s1本身是按值传递的,而且这个副本不能在函数内部进行更改。因此,您可以在函数内部执行类似++s1的操作,因此指针将始终指向相同的内存位置。

<强> 4。 char* const s1

这类似于案例3,但没有s1指向标记为常量的内存。因此,指向的内容s1可以像情况1一样改变,但指针是常量。