C - 'char **' отличается по уровням косвенности от 'char (*) [6]' - PullRequest
12 голосов
/ 23 сентября 2011

Может кто-нибудь объяснить мне, что не так со следующим и, что более важно, почему?

int main( int argc, char *argv[] )
{
    char array[] = "array";
    char **test;
    test = &array;

    *test[0] = 'Z';

    printf( "%s\n", array );

    return 0;
}

РЕДАКТИРОВАТЬ

Мой пример выше основан на функциикак это, что рухнуло:

void apple( char **pp )
{
    *pp = malloc( 123 );
    *pp[0] = 'a'; // technically this is correct but in bad form
    *pp[1] = 'b'; // incorrect but no crash
    *pp[2] = '\0'; // incorrect and crash
}

Как указал мне Вон Като, хотя *pp[0] = 'a'; не дает сбой, это в плохой форме.Правильная форма - круглые скобки

void apple( char **pp )
{
    *pp = malloc( 123 );
    (*pp)[0] = 'a'; // correct
    (*pp)[1] = 'b'; // correct
    (*pp)[2] = '\0'; // correct
}

Также, как указал другой автор, М.К. часто задаваемые вопросы охватывают разницу между массивами и указателями: http://www.lysator.liu.se/c/c-faq/c-2.html

Ответы [ 3 ]

11 голосов
/ 23 сентября 2011

test = &array

неверно, потому что тест относится к типу char**, а &array является char(*)[6] и отличается от char**

Массив не совпадает с типом char*, хотя C в некоторых случаях неявно преобразует между типом массива и char*, но это не один из них. По сути, ожидание того, что char* совпадает с типом массива (например, char[6]), неверно, и поэтому ожидание того, что получение адреса массива приведет к char**, также неверно.

3 голосов
/ 23 сентября 2011

Это будет способ сделать то, что вы пытаетесь сделать:

int main( int argc, char *argv[] )
{
  char array[] = "array";
  char (*test)[6];
  test = &array;

  (*test)[0] = 'Z';

  printf( "%s\n", array );

  return 0;
}

test - это указатель на массив, а массив отличается от указателя, даже если C делает этоЛегко использовать один, как другой в моих случаях.

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

int main( int argc, char *argv[] )
{
  char array[] = "array";
  char *test;
  test = array;  // same as test = &array[0];

  test[0] = 'Z';

  printf( "%s\n", array );

  return 0;
}
1 голос
/ 23 сентября 2011

char **test; - это указатель на указатель, но если вы собираетесь взять адрес всего массива, то он должен быть указателем на весь массив, т.е. char (*test)[6];

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...