2011-01-06 3 views
1

Это похоже на простую проблему, но для меня это неинтуитивно.Определение типов данных в цикле

Скажет у вас есть цикл, как это:

int i; 
for(i=0;i<10;i++){ 
float b = 25.2; 
float c; 
c=b+i; 
} 

Есть ли какие-то негативные последствия для определения б, как поплавок в каждом цикле? Я думал, что это было бы, но я не уверен, потому что я видел код, который работает с этим ...

Спасибо ...

ответ

5

Это нормально, и на самом деле я не думаю, что это имеет значение один бит в любом достойном компиляторе, если вы используете только float внутри цикла.

Это имеет смысл для четкости кода, чтобы поместить его в петлю, но в основном это вопрос вкуса.

Но берегитесь для ситуаций, как

int i,j; 
for (i=0;i<count;i++) 
{ 
    int j; 
    // stuff 
} 

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

редактировать просто проверял, gcc компилируется по-разному, но с -O3 генерируемой сборка идентична. Тест с gcc -S file.c. Обновление: -O1 достаточно, и это на самом деле зависит от порядка, который вы объявляете переменными. Если в вашем примере float был объявлен ниже int i;, скомпилированная сборка будет по-прежнему идентична.

+0

Что это такое -03 и -01? –

+0

@O_O: Уровни оптимизации в GCC, '-O1' через' -O3' (это буква O, а не число 0) говорят компилятору оптимизировать код от «немного» до «довольно много». '-Os' инструктирует компилятор оптимизировать размер кода. См. Http://stackoverflow.com/questions/1778538/how-many-gcc-optimization-levels-are-there – nmichaels

+0

Это флаги оптимизации. Чем больше число, тем больше фокусов. Но трюки также могут иметь недостатки: оптимизированная сборка может быть быстрее, но больше, а отлаживаемый (высоко) оптимизированный код может быть сложнее, так как соотношение 1: 1 с кодом C еще далеко. – mvds

1

Предполагая, что компилятор не оптимизирует здесь, есть небольшой штраф, выплачиваемый при распределении поплавка в каждом цикле. Вероятно, было бы лучше объявить float вне цикла.

Это зависит от кода. Иногда это чище, чтобы объявить такую ​​переменную. Цена, которую вы платите в производительности, вероятно, довольно мала.

0

Вы не инициализируете b, поэтому вы вызываете неопределенное поведение, используя его.

Если вы беспокоитесь о проблемах с производительностью, компилятор может просто оптимизировать распределение.

+0

oops, отредактированный код, чтобы исправить инициализацию для значения b .. –

-2

Если определить переменную в блоке (вещи заключены в фигурные скобки) он просто ограничивает его объем, вы можете» t использовать его снаружи. Это просто делает программу более чистой.

Программа может выделить переменные в стеке на открытии bracet и капельной на закрытии bracet, но хороший компилятор должен делать это на месте входа и выхода из подпрограммы (метод).

Кроме того, это функция C++ и действительно шаг вперед к хорошо структурированному программированию (а также делает программирование на C++ немного похожим на языки скриптов, где вам не нужно объявлять переменные, но не расскажите об этом серьезным программистам на C или Java).

+0

Насколько я знаю, объявление переменной в начале любого блока - это функция C, а не только C++. – mvds

+0

C++ допускает произвольное объявление новых переменных в любой точке блока, тогда как строгий C89 разрешает его только в начале блока. Это не относится к этому примеру. C99 также допускает такое же поведение объявления переменной, как и C++, и это поведение некоторое время являлось частью расширений компилятора, например GNU gcc. – birryree

+0

Я помню старые времена, когда все локальные переменные должны были быть указаны перед любым кодом. Возможно, это был более ранний стандарт C. (Или, может быть, я неправильно помню, я очень стар!) Хм, в нем говорится, что в C объявления должны быть в начале * блока *, а не функции: http://docs.hp.com/en/92501 -90029/ch01s03.html # d0e837 Да, наверное, ты прав. – ern0

3

В компиляторах pre-C99 для каждой итерации часто использовалось одно и то же пространство стека, поэтому на самом деле не было влияния на производительность для объявления переменной в цикле, поскольку не требовалось выделять больше пространства стека во время последовательных итераций , Я думаю, что компиляторы C99 делают что-то подобное, но я точно не знаю.

Большинство компиляторов просто оптимизируют это. Хуже всего то, что вы создаете новый флоат в стеке, что является чрезвычайно недорогой операцией на большинстве архитектур. Могут быть случаи, когда еще быстрее объявлять переменную непосредственно перед использованием. Хотя, если ваша программа чувствительна к производительности, для начала вам, вероятно, следует использовать язык ассемблера.

C99 и более поздние версии указывают, что переменные привязаны к циклу, в котором они созданы, в то время как более ранние версии C неоднозначны. Различные компиляторы реализуют его по-разному. Это важно знать, потому что вы можете столкнуться с конфликтами именования в компиляторах pre C99, если переменная с тем же именем существует в области функции, содержащей цикл (поскольку они будут обрабатывать переменную как область действия функции).

Лично я объявляю переменные в цикле все время. Он хорошо работает и четко указывает, что переменные существуют для использования в этом цикле. Это вопрос структурирования вашего кода таким образом, который четко указывает на намерения этого кода.

Смежные вопросы