如何给const char **赋值?

3
如果我声明一个变量const char ** stringTable,如果它是const的,我应该如何将值放入其中?(它必须是const,因为我要使用的函数将const char **作为参数。)
编辑: 不,你不能隐式地从char **转换为const char **。编译器会报错: 无法将参数3从“char **”转换为“const char **”
8个回答

5

哇,我很惊讶没有人理解这个问题!也许我可以获得一个死灵法师徽章。隐式的const强制转换只会扫描一层深度。因此,char* 可以变成 const char*,但它不会深入到 char** 类型内部去找需要改变的内容,使其成为 const char**

#include <iostream>
using namespace std;

void print3( const char **three ) {
        for ( int x = 0; x < 3; ++ x ) {
                cerr << three[x];
        }
}

int main() {
         // "three" holds pointers to chars that can't be changed
        const char **three = (const char**) malloc( sizeof( char** ) * 3 );
        char a[5], b[5], c[5]; // strings on the stack can be changed
        strcpy( a, "abc" ); // copy const string into non-const string
        strcpy( b, "def" );
        strcpy( c, "efg" );
        three[0] = a; // ok: we won't change a through three
        three[1] = b; // and the (char*) to (const char*) conversion
        three[2] = c; // is just one level deep
        print3( three ); // print3 gets the type it wants
        cerr << endl;
        return 0;
}

我也很惊讶没有其他人得到这个答案,干得好先生 :) - Emil Eriksson

4
除了其他提到的可以将char**传递给接受const char **的函数之外, const char**是指向const char*的非常量指针,您可以声明它并自由地放置const char*类型的值。
另一方面,如果您将其声明为const char * const *const char * const * const,则无法这样做。
yourfunc(const char **p);
...
const char *array_str[10];
array_str[0] = "foo"; /* OK, literal is a const char[] */
yourfunc(array_str);

这里是 cdecl 的说明:

cdecl> explain const char **table
declare table as pointer to pointer to const char
cdecl> explain const char * const *table
declare table as pointer to const pointer to const char
cdecl> explain const char * const * const table
declare table as const pointer to const pointer to const char

3

那个const声明是对函数的保证,你不需要履行它。这意味着函数将保持您的数组不变(只读取)。因此,您可以将非const变量传递给期望const的函数。


你可以将 char* 传递给期望 const char* 的函数。但是你不能将 char** 作为 const char** 传递。不过这并不是什么大问题,隐式转换只能在一层深度上工作,以保持简单。 - Potatoswatter

3
您可以将char **传递给声明为接受const char **的函数--值得查看MSDN上有关const文档

1

char ** 可以转换为 const char **,因此如果您想要调用一个以 const char ** 作为参数的函数,只需提供您的 char **,它将被隐式转换。

如果你想要编写一个以 const char ** 作为参数并修改其引用的 char 数据的函数,则会与编译器的契约发生冲突,即使您可能会通过强制转换来使其工作!


你可以改变指针,但不能改变它所指向的数据。例如:const char **c; const char *str = "my string"; c = &str;//合法 - Fire Lancer
此外,更改 const char ** 指向的指针是合法的,即 *c = str//legal。 - Fire Lancer

1

使用我的编译器(cygwin中的gcc版本3.4.4),我发现我可以将char *传递给const char *,但不能像大多数答案所说的那样将char **传递给const char **

这里有一种方法可以构建出可行的解决方案;也许它会对你有所帮助。

void printstring( const char **s ) {
  printf( "%s\n", *s );
}

int main( int argc, char** argv ) {

  char *x = "foo";  // here you have a regular mutable string

  const char *x2 = x;  // you can convert that to a constant string

  const char **y = &x2;  // you can assign the address of the const char *

  printstring(y);


}

char *x = "foo" 不应该编译通过,因为 "foo" 是 const char*。不需要 x2,因为你可以将一个 char* 赋值给一个 const char** 数组。 - Potatoswatter

0

你可以使用强制类型转换操作符来取消 const char* 的常量属性:(char*)

void do_something(const char* s)
{
char* p=(char*)s;
p[0]='A';
}

使用与字符数组 char** 相同的思路


0

const char ** 表示底层字符是常量。因此,您不能执行以下操作:

const char **foo = ...;
**foo = 'a';   // not legal

但是没有任何东西阻止您操纵指针本身:

// all the following is legal
const char **foo = 0;

foo = (const char **)calloc(10, sizeof(const char *));

foo[0] = strdup("foo");
foo[1] = strdup("baz");

话虽如此,如果您确实想修改实际的字符数据,您可以使用非const指针并进行强制转换:

char **foo = ...;
func((const char **)foo);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接