Передача строки C и использование ее с локальным указателем - PullRequest
0 голосов
/ 16 октября 2018

Глядя на этот код из Зло Arduino Strings

void PrintString(const char *str) {
    const char *p;
    p = str;
    while (*p) {
        Serial.print(*p);
        p++;
    }
}

Я искал, чтобы уменьшить / сжать его.Во-первых, это кажется эквивалентным:

void PrintString(const char *str) {
    const char *p;
    p = str;
    while (*p)
        Serial.print(*p++);
}

Теперь, глядя на первые две строки, как я могу объединить следующие две строки, возможно ли это?

    const char *p;
    p = str;

Могу ли ясделай это?

    const char *p = str;

Это может показаться вероятным, но выглядит неуравновешенным, так как справа нет звездочки.Я попробовал это, и это, кажется, работает, но мне было интересно, было ли это правильно, и беспокоился, что позже я получу некоторую трудную для отслеживания ошибку во время выполнения, дальше по линии.

Однако эта строка ниже явно неверна (так как она изменит указатель p, чтобы он указывал на местоположение, заданное значением первого символа строки C str):

    const char *p = *str;

Ответы [ 4 ]

0 голосов
/ 16 октября 2018
const char *p = str;

Это может показаться вероятным, но выглядит неуравновешенным, так как справа нет звездочки.

Если вы разделили элементы из приведенного выше фрагментаправильно он вообще не будет выглядеть " несбалансированным ":

  • const char* - это тип (указатель на константные символы)
  • p и str являются переменными, оба указателя (на const char)

Вы можете написать выше, используя какой-то нетрадиционный макет, такой как:

const char *  /* Note the lack of a semicolon */
p = str;

Приведенный выше код заканчиваетсяp определяется как указатель на char и содержит значение str.

Вы получаете тот же "результат" для приведенного ниже кода

const char *p;
p = str;

Обратите внимание, что первыйназывается «инициализация», тогда как последняя называется «назначение».

0 голосов
/ 16 октября 2018

Вы можете опустить использование указателя p, напрямую использовать аргумент указателя str, поскольку он является копией указателя на постоянное содержимое.

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

void PrintString(const char *str) {
    while (*str) Serial.print(*str++);
}
0 голосов
/ 16 октября 2018

Как насчет замены while на for.Вот мое мнение:

void PrintString(const char *str)
{
    for(const char* p = str; *p; p++)
        Serial.print(*p);
}

Я думаю, это тоже может сработать:

void PrintString(const char *str) {
    for(const char* p = str; *p; Serial.print(*(++p)))
        ;
}

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

void PrintString(const char* str) {
    for( ; *str; Serial.print(*(++str)))
        ;
}
0 голосов
/ 16 октября 2018

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

Что вы можете сделать, чтобы немного улучшить читаемость, и это косметическое изменение, вместо этого использовать цикл for:

void PrintString (const char *str) 
{
    for(const char* p=str; *p != '\0'; p++)
    {
        Serial.print(*p);
    }
}

В качестве альтернативы:

void PrintString (const char *str) 
{
    for(size_t i=0; str[i] != '\0'; i++)
    {
        Serial.print(str[i]);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...