LINUX.ORG.RU

do..while работает не так как надо

 


0

1

#define MAX(A, B) ((A) > (B)) ? (A) : (B)

ymax = 4;
s = 4;
x = 0;

            do
            {
                y = s - x;
                printf("%d, %d\n", x, y);
                x++;
            }
            while (y != MAX(s - ymax, 0));

Почему при s = 4 оно выходит после первой итерации? Должно же стать y = 4, 3, 2, 1, 0; а оно выходит после y=4. последнее условие получается так: while (y != MAX(0, 0)) -> while (y != 0), а при y = 4 выкидывает за пределы while.

Кто подскажет почему так?



Последнее исправление: beastie (всего исправлений: 2)

наверное, проблема с define MAX. Уверен, что если сделать функцию max, то всё будет работать корректно

// мимо крокодил

Sahas ★★★★☆
()

Вроде так

while (y != MAX(s - ymax, 0))
while (4 != ((0) > (0)) ? (0) : (0))
while (4 != (0 > 0) ? 0 : 0)
while (4 != false ? 0 : 0)
while (0)

Поэтому

#define MAX(A, B) ((A) > (B) ? (A) : (B))

thesis ★★★★★
()
Последнее исправление: thesis (всего исправлений: 1)
Ответ на: Вроде так от thesis

Какой-то говномакрос. Если параметры — вызов функций, они будут вызваны четыре раза.

anonymous
()
Ответ на: комментарий от Edible

Если у тебя С99, запили inline функцию и не имей проблем c приоритетами и double evaluation

inline int max(int a, int b) {
    return a > b ? a : b;
}

http://ideone.com/qDRkt5

KennyMinigun ★★★★★
()
Последнее исправление: KennyMinigun (всего исправлений: 1)
Ответ на: комментарий от thesis

за шесть лет на ЛОРе дефайны-то писать не наловчился?

Час ночи. Я уже на автомате всякую хрень пишу и не понимаю чего написал.

Edible
() автор топика
Ответ на: комментарий от Edible

Ну, ANSI C — это боль и страдания (заради высшего блага (трушности)). Ты уверен в своем порыве мазохизма?

KennyMinigun ★★★★★
()
Ответ на: комментарий от Edible

С99(и с11) это не какой-то там GCC-C, а стандарт, поддерживается всеми нормальными компиляторами (visual studio за нормальный не считается).

anonymous
()

Не советую делать такие макросы. Если кто-нибудь сделает MAX(a++, b++) то получится полный бред

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от anonymous

Сишные генерики — это плевок в душу всем, кто хоть раз видел плюсовые шаблоны.

Gvidon ★★★★
()
Ответ на: комментарий от anonymous

классно. Однако, привык к c90. Даже переменные всегда в начале блока определяю, чтобы в случае чего cl.exe не ругался.

mittorn ★★★★★
()

Есть еще вот такое решение, которое мне очень понравилось:

#include <stdio.h>

#define MAX(TYPE, A, B)\
({                     \
  TYPE _A = (A);       \
  TYPE _B = (B);       \
  _A > _B ? _A : _B;   \
})

void main()
{
   printf("%d\n", MAX(int, 5, 4));
   printf("%f\n", MAX(float, 1.2, 2.8));

   return 0;
}

Moreo
()
Ответ на: комментарий от i-rinat

это расширение компилятора Visual C++.

И? Не понял связи. Я всегда так под gcc пишу, под Visual C++ никогда не писал. Qt/gcc/clang

Moreo
()

я тут мимокрокодил, однако хочу заметить, что

#define MAX(A, B) ((A) > (B)) ? (A) : (B)

тернарные операторы это, конечно, прекрасно и очень хорошо, но нечитаемо

reprimand ★★★★★
()
Ответ на: комментарий от Moreo

И? Не понял связи.

Ты высказываешься против использования особенностей (документированных) компилятора, аргументируя это отсутствием этих особенностей в стандарте, а сам приводишь некорректный код. Это достаточно ясно?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Я не требую использовать мой код - тот кусок где не по стандарту не влияет на работу, а является демонстрацией использования кода по-стандарту. Ваш код не по стандарту in core.

Moreo
()
Ответ на: комментарий от Moreo

Стало читаемее?

Причём тут это? Посыл же был в «ты не сможешь написать это if'ами», разве нет? Ищешь за что зацепиться, чтобы правоту отстоять. (Я тоже так люблю делать.)

Читаемость это сложное понятие. Для питонистов a if a > b else b читаемо и понятно. А для reprimand тернарные операции не читаемы. Всё зависит от опыта и личных предпочтений.

i-rinat ★★★★★
()
Ответ на: комментарий от vzzo

Но он же не сказал «без использования расширений компилятора».

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

А для reprimand тернарные операции не читаемы. Всё зависит от опыта и личных предпочтений.

Я пишу код таким образом, чтобы человеку после меня (или со мной) при сопровождении снижался риск ошибки и всяких казусов. Ну и для себя заодно если придется возвращаться.

reprimand ★★★★★
()
Ответ на: комментарий от reprimand

Я как-то уже привык писать:

    fcd = gtk_file_chooser_dialog_new(dialog_title, NULL,
                                      p->save_as ? GTK_FILE_CHOOSER_ACTION_SAVE
                                                 : GTK_FILE_CHOOSER_ACTION_OPEN,
                                      close_button_title, GTK_RESPONSE_CANCEL,
                                      open_button_title, GTK_RESPONSE_OK, NULL);

Хотя я допускаю, что возможно поэтому кроме меня этот код никто не пилит. Печаль.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Хотя я допускаю, что возможно поэтому кроме меня этот код никто не пилит. Печаль.

:(

reprimand ★★★★★
()
Ответ на: комментарий от i-rinat

void main() — это расширение компилятора Visual C++.

Нет, Plan 9 C Compiler, например. Правда там нужен вызов exits вместо return, но тем не менее.

korvin_ ★★★★★
()
Ответ на: комментарий от reprimand

тернарные операторы это, конечно, прекрасно и очень хорошо, но нечитаемо

Будешь смеяться, но тернарки надо читать с интонацией, соответствующей знакам пунктуации.

KennyMinigun ★★★★★
()
Ответ на: комментарий от i-rinat

а ещё тернарный оператор удобно использовать в цепочке.

 cond1?ex1:cond2?ex2:ex3 

кроме меня этот код читает и пишет ещё несколько человек, которых всё полностью устраивает.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.