【问题标题】:Why do string functions have some parameters as const char *( pointers to constant characters)?为什么字符串函数有一些参数作为 const char *(指向常量字符的指针)?
【发布时间】:2017-02-19 10:41:11
【问题描述】:

可以在 C 中修改字符串(字符数组),但不能修改字符串文字。但是为什么像 strlen(const char *str) 这样的字符串函数有一个指向常量字符的指针呢?

【问题讨论】:

  • 请注意,const 和 "constant" 在 C 中实际上是两个不同的东西。const 表示只读。 “常量”表达式是可以在编译时评估的表达式。例如:const int r = rand();r 的值显然不是常量,但初始化后不能合法更改。

标签: c


【解决方案1】:

因为他们不修改(也不需要修改)他们的参数字符串。这就是const 的意思。

如果strlen 的参数被声明为char *(不是const),您将无法使用strlen 来确定常量字符串的长度。例如

size_t my_own_strlen(char *str) { /* whatever */ }

const char hello[] = "Hello";

size_t l1 = my_own_strlen(hello); // Error: cannot convert `const char *` to `char *`
size_t l2 = strlen(hello);        // OK

将该参数声明为const char * 使strlen 适用于常量和非常量字符串。

【讨论】:

    【解决方案2】:

    const T* p表示p指向的内存不能通过变量p修改。它代表了一个承诺,p 不会用于修改指向的内存。这并不意味着p 指向永远无法修改的内存。

    T* 转换为const T* 总是安全的:

    T value;
    T* q = &value; // Not const.
    const T* p = q; // No cast necessary.
    p = &value; // No cast necessary here either.
    

    因此,如果字符串函数不改变其参数,则将其参数声明为const char* 并没有什么坏处:

    const char* s = "string literal";
    strlen(s); // This is legal.
    
    char buf[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
    strlen(buf); // This is legal too.
    

    但是,如果参数被声明为 char*,那么您将无法const char* 传递给它。

     void foo(char* s);
    
     const char* s = "string literal";
     foo(s); // This will fail to compile.
    

    因此,如果可能的话,最好记住用const 限定指针参数,这样做可以证明函数承诺不会改变指针。

    【讨论】:

      【解决方案3】:

      这只是意味着函数不会修改指针指向的数据。为您提供一些类型安全性和优化编译器的机会。

      【讨论】:

      • 它没有提供任何优化机会,只是为了通过类型安全避免意外写入
      • 嗯,它可以帮助编译器推断该函数是纯函数。有很多优化机会。例如,编译器可以使用它来将函数调用更改为常量或执行某种 CSE
      • 该函数仍然可以丢弃 const 并修改指向的对象(如果该对象实际上不是 const,则这不是未定义的行为),因此调用代码不能假定该函数没有更改对象。
      【解决方案4】:

      strlen(const char *str) 有一个指向常量字符的指针,因为它将输入 *str 作为 只读 字符串,然后执行计算并返回值而不修改原始字符串,因为它为了计算字符串的长度,不需要修改内存中的字符串。

      【讨论】:

        猜你喜欢
        • 2011-10-19
        • 1970-01-01
        • 2021-03-09
        • 2012-03-10
        • 1970-01-01
        • 2020-03-25
        • 1970-01-01
        • 1970-01-01
        • 2011-04-21
        相关资源
        最近更新 更多