Строка C в верхнем регистре в C и С++
Пока я собирал в С++ функцию верхнего регистра, я заметил, что я не получил ожидаемый результат в C.
Функция С++
#include <iostream>
#include <cctype>
#include <cstdio>
void strupp(char* beg)
{
while (*beg++ = std::toupper(*beg));
}
int main(int charc, char* argv[])
{
char a[] = "foobar";
strupp(a);
printf("%s\n", a);
return 0;
}
Вывод ожидаемого результата:
FOOBAR
Функция C
#include <ctype.h>
#include <stdio.h>
#include <string.h>
void strupp(char* beg)
{
while (*beg++ = toupper(*beg));
}
int main(int charc, char* argv[])
{
char a[] = "foobar";
strupp(a);
printf("%s\n", a);
return 0;
}
Результат - ожидаемый результат с отсутствием первого символа
OOBAR
Кто-нибудь знает, почему результат усекается при компиляции в C?
Ответы
Ответ 1
Проблема заключается в том, что в
нет точки последовательности,
while (*beg++ = toupper(*beg));
Итак, мы имеем поведение undefined. То, что делает компилятор в этом случае, оценивает beg++
до toupper(*beg)
В C, где в С++ это делается другим путем.
Ответ 2
while (*beg++ = std::toupper(*beg));
приводит к поведению undefined.
Определяется ли *beg++
до или после std::toupper(*beg)
неуказано.
Простым решением является использование:
while (*beg = std::toupper(*beg))
++beg;
Ответ 3
Линия
while (*beg++ = toupper(*beg));
содержит побочный эффект для объекта, который используется дважды. Вы не можете знать, выполняется ли бег ++ до или после * beg (внутри toupper). Вам просто повезло, что обе реализации показывают оба поведения, так как я уверен, что это одинаково для С++. (Тем не менее, были некоторые изменения правил для С++ 11, о которых я не уверен - по-прежнему, это плохой стиль.)
Просто переместите параметр beg++ из условия:
while (*beg = toupper(*beg)) beg++;
Ответ 4
в отношении вышеприведенного ответа, "f" никогда не передается внутри функции, вы должны попробовать это:
while ((*beg = (char) toupper(*beg))) beg++;