Подтвердить что ты не робот

Строка 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?

4b9b3361

Ответ 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++;