Несоответствие указателя / целочисленного типа в условном выражении

Поэтому я уже посмотрел другие посты с похожими заголовками, но ни один из предложенных ответов не работает для меня.

У меня есть функция, которая вычисляет частоту символа в строке:

int frequency(char *s, char c) {
  int i;
  for (i=0; s[i]; s[i]==c ? i++ : s++);

  return i;
}

Он работает правильно, но компилятор выдает мне следующую ошибку:

warning: pointer/integer type mismatch in conditional expression [enabled by default]

Может кто-нибудь объяснить, почему

ура

3 ответа

Решение

i++ имеет тип intв то время как тип s++ является char *, В условном выражении вы не можете иметь два разных типа в ветвях "then" и "else", отсюда и предупреждение.

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

int frequency(const char *s, char c)
{
    int i;
    for (i = 0; s[i];)
         if s[i] == c
             i++;
         else
             s++;

    return i;
}

Каждое выражение должно иметь тип. Для этого выражения

s[i]==c ? i++ : s++

не ясно, какой тип должен быть. i++ дает целое число, и s++ дает char *, char * конвертируется в int, который в основном является логическим значением того, является ли указатель не нулевым. Таким образом, имея тип выражения intкомпилятор может заставить его работать, но так как это очень странная ситуация, вы получаете предупреждение.

Код, как написано, использует параметр s и как указатель на символ, и как массив символов, проиндексированный i, for цикл используется для перебора строки, но начало строки перемещается, когда соответствующий символ не найден.

Это очень умный код. Умный код - редко хорошая вещь.

"It works" потому что результат выражения s[i]==c ? i++ : s++ не используется. Каждая ветвь выполняет действие, возвращая значение другого типа. Ни одно из этих значений не используется в другом выражении.

Я обычно использую for циклы для выполнения определенного количества итераций. В этом случае я думаю, что while цикл более уместен.

С помощью s в качестве указателя

int frequency(char *s, char c) {
  int count = 0;

  while (*s != 0) {
    if (*s == c) { 
      count++; 
    }
    s++;
  }

  return count;
}

С помощью s как массив символов

int frequency(char s[], char c) {
  int count = 0;
  int current = 0;

  while (s[current] != 0) {
    if (s[current] == c) { 
      count++; 
    }
    current++;
  }

  return count;
}
Другие вопросы по тегам