const char ** vs const char * мутация - PullRequest
0 голосов
/ 24 мая 2019

В моем коде я пытаюсь сделать следующее:

// Attempt #1
const char** strings;
strings[0] = "apple";
strings[1] = "orange";
strings[3] = "bananas";

// Attempt #2
const char* chars;
chars[0] = 'a'; // Error
chars[1] = 'b'; // Error again

Когда я компилирую GCC, все в порядке с Попыткой # 1, но с Попыткой # 2 он говорит, что LHS должен быть назначаемым.По-видимому, в силу идентификатора const массив символов не может быть назначен.Зачем?

Ответы [ 2 ]

2 голосов
/ 24 мая 2019

Читать const char** как «(неконстантный) указатель на (не константный) указатель на постоянный символ». Вам разрешено изменять strings и strings[n], но не strings[n][m].

const char* - это только один уровень. Вы можете изменить chars, но не chars[n].

То, как вы сделали бы strings[n] неизменяемым, это с помощью const char* const* - «(неконстантный) указатель на const указатель на постоянный символ»

Также обратите внимание, что в вашем примере strings и chars не инициализированы. Вам нужно будет инициализировать их, прежде чем вы сможете получить к ним доступ.

Этот вопрос содержит методы чтения объявлений на языке Си. В этих простых случаях вы читаете справа налево.

0 голосов
/ 24 мая 2019

char *string - указатель на массив char.что-то вроде этого:

             .----.   .----.   .----.
             | s  | - | a  | - | m  |
             .----.   .----.   .----.
               ^
               |
char *string --.

все равно, что у вас есть массив и указатель на массив:

char strArr[3];
char *ptrToStr = &strArr;

вы можете инициализировать char * различными способами:

char *string;
scanf("%as", string);
/* if you don't allocate buffer for `*string`, and specify "a" in string format, 
then `scanf` will do it for you. this is GNU-only extension. */

char *string2;
string2 = (char *) malloc (BUFF_SIZE);
sprintf(string2, "%s" , "Ghasem Ramezani");

...

Но char **string - это указатель на указатель на char массив .что-то вроде этого:

                     .----.   .----.   .----.
                     | s  | - | a  | - | 1  |
                     .----.   .----.   .----.
                       ^
                       |
   .->  char *string --.
   |                 .----.   .----.   .----.
   |                 | s  | - | a  | - | 2  |
   |                 .----.   .----.   .----.
   |                   ^
   |                   |
   .-> char *string2 --.
   |
   .-------------.
                 |
char **strArr ---.

например, char **, вы помните аргумент argv в main ()?это точно тип char **.давайте рассмотрим пример:

/*1*/ #include <stdio.h>
/*2*/ int main(int argc, char *argv[]) {
/*3*/   for (int i = 0; i < argc; ++i)
/*4*/     puts(argv[i]);
/*5*/   return 0;
/*6*/ }
$> gcc -o output main.c
$> ./output ghasem ramezani
./output
ghasem
ramezani
$>

, как вы можете видеть в строке 2, мы можем написать char *[] вместо char **.Зачем ?потому что, как я и @Kevin сказали:

Считайте const char ** как «(неконстантный) указатель на (не константный) указатель на постоянный символ».

...