Objective-C "const" вопрос - PullRequest
       4

Objective-C "const" вопрос

1 голос
/ 17 октября 2010

Википедия говорит, что "const" - это "... особый тип переменной, значение которой обычно не может быть изменено программой во время ее выполнения ..."

Если это так, то почему:

const char *words[4] = { "aardvark", "abacus", 
                             "allude", "zygote" };

    *words = "first";
    words[1] = "second";

    int wordCount = 4;

    int i;
    for (i = 0; i < wordCount; i++) {
        NSLog (@"%s is %d characters long",
               words[i], strlen(words[i]));
    }

имеют вывод: "первый" «Второй» «Намекают» "зигота" (очевидно, с длиной и т. д.)

Я думал, что весь смысл "const" состоит в том, чтобы предотвратить изменение переменной ??

Ответы [ 2 ]

19 голосов
/ 17 октября 2010

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

char const* const words[4] = { "aardvark", "abacus", "allude", "zygote" };
//   ^      ^
//   |      This makes words[x] = "abc"; fails.
//   |
//   This makes words[x][y] = 'a'; fails
3 голосов
/ 20 марта 2013

Расшифруйте утверждение:

const char *words[4] = { "aardvark", "abacus", "allude", "zygote" };

Это говорит: «Я хочу массив из 4 указателей на постоянные символы. Эти постоянные символы должны быть ...»

В памяти вы получите следующее:

0x04, // The pointer to the array of words
0x14, 0x1d, 0x24, 0x3b, // The 4 pointers within words
'a','a','r','d','v','a','r','k','\0','a','b','a','c','u','s','\0',
'a','l','l','u','d','e','\0','z','y','g','o','t','e','\0'

Каждый из этих персонажей не может быть изменен. Вы не можете сделать это, потому что вы меняете букву:

words[0][0] = 'b';

Никто ничего не сказал об этих указателях, хотя.

words[0] = "new string";

В результате вы получите это в памяти:

0x04, // The pointer to the array of words
<b>0x42</b>, 0x1d, 0x24, 0x3b, // The 4 pointers within words, <b>note the first one changed</b>
'a','a','r','d','v','a','r','k','\0','a','b','a','c','u','s','\0',
'a','l','l','u','d','e','\0','z','y','g','o','t','e','\0',
<b>'n','e','w',' ','s','t','r','i','n','g','\0'</b>

Обратите внимание, что в памяти ни одна из исходных строк не изменилась. Произошло только два изменения:

1 - Первый указатель в словах изменился, чтобы указывать на новый адрес. 2 - Символы для «новой строки» были добавлены в память по этому новому адресу.

Теперь расшифруйте это утверждение:

 char const* const words[4] = { "aardvark", "abacus", "allude", "zygote" };

Это говорит: «Я хочу массив из 4 константных указателей на константные символы. Эти константные символы должны быть ...» Этим указателям никогда не разрешается указывать на что-либо еще. Этим персонажам никогда нельзя быть чем-либо еще.

Внимательный читатель может спросить о том, должен ли указатель на массив быть постоянным. Ответ ... Я не совсем уверен. Я хочу сказать, что подразумевается, что он постоянный, но я не совсем уверен, что аккумулятор моего ноутбука вот-вот разрядится.

Надеюсь, это поможет любому, кто с этим столкнется!

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