Как поместить значения в const char **? - PullRequest
2 голосов
/ 23 января 2009

Если я объявляю переменную const char ** stringTable, как я могу иметь возможность помещать в нее значения, если это const? (Это должно быть const, потому что функция, которую я должен использовать, принимает const char ** в качестве параметра.)

Edit: Нет, вы не можете конвертировать из char ** в const char ** неявно. Компилятор жалуется: невозможно преобразовать параметр 3 из 'char **' в 'const char **'

Ответы [ 8 ]

5 голосов
/ 15 января 2010

Ух ты, я удивлен, что никто не получил это! Может быть, я могу получить значок некроманта. Неявное приведение констант сканирует только один уровень. Таким образом, 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;
}
4 голосов
/ 23 января 2009

Помимо других упоминаний, что вы можете передать 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
4 голосов
/ 23 января 2009

Это объявление const является гарантией функции, вам не нужно ее заполнять. Это означает, что функция сохранит ваш массив нетронутым (он просто будет читать). Таким образом, вы можете передать неконстантную переменную в функцию, ожидающую const.

3 голосов
/ 23 января 2009

Вы можете передать char ** в функцию, объявленную как принимающую const char ** - Возможно, стоит взглянуть на документацию для const в MSDN

1 голос
/ 24 января 2009

С моим компилятором (gcc версии 3.4.4 в cygwin) я обнаружил, что могу передать 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);


}
1 голос
/ 23 января 2009

char ** можно преобразовать в const char **, поэтому, если вы хотите вызвать функцию, которая принимает const char ** в качестве параметра, просто укажите char **, и она будет неявно преобразованный.

Если вы хотите написать функцию, которая принимает const char ** в качестве параметра и затем изменяет данные char, на которые она ссылается, вы нарушаете контракт со своим компилятором, даже если вы можете это работает через приведения!

0 голосов
/ 15 января 2010

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");

Тем не менее, если вы хотите изменить фактические символьные данные, вы можете использовать неконстантный указатель и привести его:

char **foo = ...;
func((const char **)foo);
0 голосов
/ 24 января 2009

вы можете отменить преобразование char *, используя оператор приведения: (char *)

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

использовать ту же идею с массивами char **

...