Каков результат уменьшения указателя на символ? - PullRequest
0 голосов
/ 30 ноября 2018

Итак, я изучал код для пользовательской оболочки linux, и мне трудно разобраться в этом разделе:

// add null to the end
char *end;
end = tokenized + strlen(tokenized) - 1;
end--;
*(end + 1) = '\0'; 

Я не понимаю, что дает уменьшение указателя на символ и как работает этот разделВ общем, я понимаю, что это указатель конца на последнюю позицию массива токенов, но я не понимаю следующие две строки.Если что-то подобное было опубликовано, я не против предоставить мне ссылки (хотя я провел много исследований).Спасибо!

Также быстрый вопрос: я не верю, что end - это массив.Я не прав в этом?

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018
char *end;
end = tokenized + strlen(tokenized) - 1; // 
end--;
*(end + 1) = '\0'; 

strlen (tokenized)

Это смещение нулевого терминатора в строке tokenized.Это означает, что если вы увеличиваете указатель на это смещение (количество ненулевых символов), вы получаете указатель на индекс сразу после последнего символа.Чтобы получить индекс прямо на последний символ, вы вычтите его из смещения.

Let offset = strlen(tokenized) - 1

tokenized + смещение

Thisозначает, что указатель tokenized перемещен на смещение .Если указатель будет ссылаться на 1 байт, это означает, что он просто увеличивается на 1, если его 2 байта на 2, и так далее.Это потому, что если у вас есть, например, массив целых чисел, вы хотите получить доступ только к целым числам при смещении указателя массива.Размер int не менее 2 байтов, поэтому при увеличении указатель будет перемещаться не менее чем на 2 байта.

end -

То же, что и выше, уменьшает указатель на единицу, так как мы переместились к последнему символу строки, используя наше смещение, теперь мы находимся со второго до последнего символа в строке, не так много, чтобы сказать, что это эквивалентно end = end - 1;.

* (end + 1) = '\ 0'

Опять же, мы перемещаем смещение на 1 вперед по указателю, поэтому мы сновауказать на последний символ строки.Это довольно избыточно, поскольку мы только уменьшали указатель на то же смещение.Единственная разница здесь в том, что сам указатель end не изменяется.

Затем мы разыменовываем указатель и записываем в него, это означает, что мы меняем значение, на которое в данный момент указывает указательа именно последний символ строки.Мы изменили это значение на '\0', потому что это означает, что мы перемещаем завершающий нулевой байт в это место, эффективно сокращая строку путем вырезания последнего символа.

Код здесь эквивалентен

size_t len = strlen(tokenized);
tokenized[len - 1] = '\0';
char *end = tokenized + len - 2; // we still have this pointer

Обратите внимание, что мы делаем -2 сейчас, потому что мы включаем оператор end--;.Текущий end продолжает указывать на последний символ сокращенной строки.

Иллюстрация происходящего:

  1. tokenized = "hello world"; // [h e l l o w o r l d \0 ]
  2. tokenized = "hello worl"; // [h e l l o w o r l \0 \0 ]

Я не верю, что end - это массив.Я не прав в этом?

Массивы по существу просто указатели на области памяти.Есть несколько отличий, таких как sizeof результаты и доступ для записи, но вы можете сказать, что массивы - это указатели.

0 голосов
/ 30 ноября 2018

Уменьшение указателя перемещает его местоположение в памяти на предыдущий адрес.В случае строки char *, end теперь будет указывать на предыдущий символ.

// add null to the end
// declare a `char *`
char *end;
// set `end` to point to the last character of `tokenized`
end = tokenized + strlen(tokenized) - 1; 
// decrease `end`; now points to the character before the character is was pointing to
end--;
// set the character after the one `end` points to to `NUL`
*(end + 1) = '\0'; 

Я прокомментировал ваш код так, как я его понимаю ...

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