При реализации бесконечного цикла, там различие в использовании в то время как (1) по сравнению с для (;;) по сравнению с goto (в C)?

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

    class Something<TCell>
    {
        internal static TCell Sum(TCell first, TCell second)
        {
            if (typeof(TCell) == typeof(int))
                return (TCell)((object)(((int)((object)first)) + ((int)((object)second))));

            if (typeof(TCell) == typeof(double))
                return (TCell)((object)(((double)((object)first)) + ((double)((object)second))));

            return second;
        }
    }

Обратите внимание, что типыof оцениваются во время компиляции, поэтому операторы if будут удалены компилятором. Компилятор также удаляет ложные нажатия. Итак, что-то разрешило в компиляторе

        internal static int Sum(int first, int second)
        {
            return first + second;
        }
28
задан Joachim Sauer 18 February 2010 в 03:39
поделиться

8 ответов

Они эквивалентны, даже если вы отключите оптимизатор.

Пример:

#include <stdio.h>

extern void f(void) {
    while(1) {
        putchar(' ');
    }
}

extern void g(void) {
    for(;;){
        putchar(' ');
    }
}

extern void h(void) {
    z:
        putchar(' ');
    goto z;
}

Компиляция с помощью gcc -O0 дает эквивалентную сборку для всех 3 функций:

 f:
 ;  [ EXTERNAL ]
 ;
 +00000 00000fb4 80402DE9             stmdb             sp!,{r7,lr}
 +00004 00000fb8 00708DE2             add               r7,sp,#0x0
 +00008 00000fbc 2000A0E3 loc_000008: mov               r0,#0x20
 +0000c 00000fc0 0A0000EB             bl                putchar (stub)
 +00010 00000fc4 FCFFFFEA             b                 loc_000008
 ;
 ;
 g:
 ;  [ EXTERNAL ]
 ;
 +00000 00000fc8 80402DE9             stmdb             sp!,{r7,lr}
 +00004 00000fcc 00708DE2             add               r7,sp,#0x0
 +00008 00000fd0 2000A0E3 loc_000008: mov               r0,#0x20
 +0000c 00000fd4 050000EB             bl                putchar (stub)
 +00010 00000fd8 FCFFFFEA             b                 loc_000008
 ;
 ;
 h:
 ;  [ EXTERNAL ]
 ;
 +00000 00000fdc 80402DE9             stmdb             sp!,{r7,lr}
 +00004 00000fe0 00708DE2             add               r7,sp,#0x0
 +00008 00000fe4 2000A0E3 loc_000008: mov               r0,#0x20
 +0000c 00000fe8 000000EB             bl                putchar (stub)
 +00010 00000fec FCFFFFEA             b                 loc_000008
51
ответ дан 28 November 2019 в 02:38
поделиться

while(1) и for(;;) в точности эквивалентны, и оба являются хорошо понятными идиомами для кодирования бесконечных циклов.

Я бы избегал использования goto: чтобы выйти из бесконечного цикла или перейти к следующей итерации, используйте break и continue.

4
ответ дан Danilo Piazzalunga 20 November 2019 в 02:18
поделиться

Хотя нет существенной разницы, как упоминалось в других статьях, общая причина использования for (;;) вместо while (1) состоит в том, что инструменты статического анализа (и некоторые компиляторы с определенными уровнями предупреждений) часто жалуются на цикл while. 114]

Goto немного неприятен, но должен генерировать тот же код, что и остальные. Лично я придерживаюсь for (;;) (чтобы Линт был доволен), но у меня нет проблем с while (1).

3
ответ дан DrAl 20 November 2019 в 02:18
поделиться

Из того, что я помню о моих "разборочных годах", это не будет иметь большого значения (компиляторы достаточно умны ). Это больше об эстетике ИМО.

0
ответ дан jldupont 20 November 2019 в 02:18
поделиться

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

Например, если приведенное выше предложение содержится в файле utf-8 и используется файл python2.x. Если вы используете python 3 .x это еще более читаемо, так как вам не нужно префиксировать строки Юникода с 'u "', как в этом примере (но вы будете пропускать много сторонних библиотек:

separators = [u"।", u",", u"."]
text = open("indiantext.txt").read()
#This converts the encoded text to an internal unicode object, where
# all characters are properly recognized as an entity:
text = text.decode("utf-8")

#this breaks the text on the white spaces, yielding a list of words:
words = text.split()

counter = 1

output = ""
for word in words:
    #if the last char is a separator, and is joined to the word:
    if word[-1] in separators and len(word) > 1:
        #word up to the second to last char:
        output += word[:-1] + u"(%d) " % counter
        counter += 1
        #last char
        output += word[-1] +  u"(%d) " % counter
    else:
        output += word + u"(%d) " % counter
    counter += 1

print output

Это" развернутый "пример, как вы больше привыкли к Python есть более короткие способы выразить это. Вы можете изучить основы языка за пару часов, следуя учебному пособию. (например, сама http://python.org )

-121--3791878-

См. эту ссылку, чтобы имитировать вызов getJSON в методах установки/разрыва, http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=505

-121--1277132-

Я только что сравнил неоптимизированные выходные данные ассемблера gcc:

# cat while.c 
int main() {
    while(1) {};
    return 0;
}

# cat forloop.c 
int main() {
    for (;;) { };
    return 0;
}

Make assembler output:

# gcc -S while.c 
# gcc -S forloop.c 

Compare assembler files:

# diff forloop.s while.s
1c1
<   .file   "forloop.c"
---
>   .file   "while.c"

Поскольку вы видите, что существенных различий нет. Вот результат

# cat while.s 
    .file   "while.c"
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
.L2:
    jmp .L2                    # this is the loop in both cases
    .size   main, .-main
    .ident  "GCC: (GNU) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

Хотя это не является техническим доказательством того, что они одинаковы, я бы сказал, что это в 99,9% случаев.

8
ответ дан 28 November 2019 в 02:38
поделиться

Практически нет никакой разницы в сгенерированной сборке. Это скорее стилистическая проблема:

Goto - просто ooogly: прыжок назад, без явного бесконечного блока

while (1) - лучше, требует "фиктивного" условия, и вы будете часто предупреждение компилятора (уровень предупреждения 4) или инструмент статического анализа

для (;;) может быть не самым красивым, но imho подходит лучше всего, потому что эта конструкция не может иметь никакого другого значения (по сравнению с while). Но некоторые другие люди предпочитают while (1) по "той же" причине ...

4
ответ дан 28 November 2019 в 02:38
поделиться

Нет. Используйте то, что наиболее читабельно для вас

3
ответ дан 28 November 2019 в 02:38
поделиться

В C истина реализуется следующим образом (в зависимости от компилятора)

#define TRUE 1

или

#define TRUE (-1)

И ложь реализуется как

#define FALSE 0

, поэтому while (1) эквивалентно while (true) , поскольку 0 считается ложным.

while (1) == для (;;) , поскольку нет условия остановки.

, который переводится на ассемблер как

:loop
  ...
  ...
  ...
  goto loop

, поэтому, если в коде ассемблера нет инструкции ret или exit , это считается бесконечным циклом.

2
ответ дан 28 November 2019 в 02:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: