Почему моя функция для вычисления длины строки возвращает отрицательное значение? - PullRequest
0 голосов
/ 07 июля 2019

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

Я пытался использовать свое понимание адресации памяти, чтобы заставить функцию работать как задумано.

int getLength(const char *str) {
    int length;
    while (*str != '\0') {
        length += str - (++str);
    }
    return abs(length);
}

int getLength(const char *str) {
    int length;
    while (*str != '\0') {
        length += str + (++str);
    }
    return length;
}

Первая функция возвращает правильную длину, а вторая возвращает 0, почему это так?

Ответы [ 3 ]

3 голосов
/ 07 июля 2019

Обе функции неверны, потому что:

  • вы не инициализируете length, поэтому поведение не определено.
  • принятие абсолютного значения - неудачная попытка решить проблему ... исправить симптомы, но не решить проблему. Не делайте этого, исследуйте проблему.
  • length += str - (++str); имеет неопределенное поведение, потому что побочный эффект на str может произойти до или после получения значения левого операнда str.
  • length += str + (++str); является нарушением ограничения: добавление 2-х указателей в C не допускается.

Вместо этого вы должны написать:

size_t getLength(const char *str) {
    size_t length = 0;
    while (*str != '\0') {
        length++;
        str++;
    }
    return length;
}

В зависимости от целевой архитектуры может быть эффективнее только увеличивать str и вычислять разницу в конце:

size_t getLength(const char *str) {
    const char *p;
    while (*p++ != '\0')
        continue;
    /* p was incremented beyond the null terminator, hence decrease the difference by 1 */
    return p - str - 1;
}
0 голосов
/ 07 июля 2019

У ваших функций много проблем:

  1. Вы не инициализируете автоматические переменные.
  2. Ваша арифметика с указателями не имеет особого смысла (по крайней мере, я не могу понять, чтоэто логика, лежащая в основе)
  3. результат pf операций, где для одного размера у вас есть lvalue, а пост (пред) увеличение или уменьшение не определено (это говорит скорее о неопределенном поведении)

Ниже у вас есть две почти одинаковые версии функции strlen.Иногда небольшие изменения могут оказывать большое влияние на производительность функции в зависимости от целевого оборудования.

эта версия более оптимальна для целей ARM

size_t getlen(const char *s)
{
    const char *p = s;

    while(*p++);

    return p - s - 1;
}

эта лучше для целей x86

size_t getlen(const char *s)
{
    const char *p = s;

    while(*p)
    {
        p++;
    }

    return p - s;
}
0 голосов
/ 07 июля 2019

Вы должны инициализировать переменную длины в обоих примерах.

Вы по сути пытаетесь сделать:

 int getLength(const char* str) {
     int length = 0;
     while(*str != '\0') {
         length ++; // str - (++str) is always -1;
         str++;
     }
     return length;
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...