Является ли переменная с именем i неприемлемой?

Что касается соглашений об именах переменных, следует ли называть итераторы i или что-то более семантическое, например count? Если вы не используете i, почему бы и нет? Если вы считаете, что i приемлемо, есть ли случаи итерации, когда его не следует использовать?


person VirtuosiMedia    schedule 25.09.2008    source источник
comment
Взгляните на ‹stackoverflow.com/questions/101070/›, в котором рассматривается этот вопрос.   -  person Jon Ericson    schedule 25.09.2008
comment
Только в командных проектах. Потому что в команде нет i!   -  person Sedat Kapanoglu    schedule 03.11.2010


Ответы (21)


Полагаю, это зависит от контекста. Если вы просматриваете набор объектов в некоторой коллекции, то из контекста должно быть довольно очевидно, что вы делаете.

for(int i = 0; i < 10; i++)
{
    // i is well known here to be the index
    objectCollection[i].SomeProperty = someValue;
}

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

for(int currentRow = 0; currentRow < numRows; currentRow++)
{
    for(int currentCol = 0; currentCol < numCols; currentCol++)
    {
        someTable[currentRow][currentCol] = someValue;
    }
} 
person Josh    schedule 25.09.2008
comment
Я бы использовал iRow и iCol, но потом перешел на FORTRAN - person Martin Beckett; 25.09.2008
comment
FORTRAN по-прежнему великолепен для научных вычислений. Лол, ученые действительно будут смеяться над вами, если вы упомянете другие языки. - person Josh; 25.09.2008
comment
Удвойте любую односимвольную переменную, чтобы поиск был полезным. ii v. i, xx v. x. - person user7116; 25.09.2008
comment
Уловка «удвоить любой одиночный символ» менее полезна, когда у вас есть IDE со встроенными мастерами рефакторинга. Что касается ответа Джоша, это, по сути, идеальный пример того, что делать. Респект! - person Outlaw Programmer; 25.09.2008
comment
для вложенного цикла над двумерным массивом по соглашению следует использовать i, а затем j. currentRow и currentCol слишком многословны :-) Тем не менее, я согласен с тем, что если что-то неясно, не используйте i - person Orion Edwards; 25.09.2008
comment
currentRow и currentCol можно легко назвать просто row и col. - person mat_geek; 25.09.2008
comment
Орион Эдвардс прав. Во втором случае лучше использовать i, j. - person Camilo Díaz Repka; 04.10.2008
comment
Однако в первом случае вам будет лучше использовать foreach (при условии, что язык поддерживает его). - person Dan Walker; 10.10.2008
comment
Для двумерного массива, представляющего сетку, я часто использую x и y, которые соответствуют концепции осей x и y. - person Thomas Owens; 10.10.2008
comment
согласен с mat_geek насчет row & col - person demoncodemonkey; 10.02.2009

«i» означает «счетчик циклов» для программиста. В этом нет ничего плохого.

person Andy Lester    schedule 25.09.2008

Вот еще один пример того, что совершенно нормально:

foreach (Product p in ProductList)
{
    // Do something with p
}
person Ian P    schedule 25.09.2008
comment
Абсолютно. Никто никогда не жалуется, что математические доказательства, которые читают, рассматривают непрерывную функцию f, непонятны, потому что функция называется f, а не a_continuous_function. - person Steve Jessop; 25.09.2008

Я обычно использую i, j, k для очень локализованных циклов (существуют только в течение короткого периода с точки зрения количества исходных строк). Для переменных, которые существуют в большей исходной области, я обычно использую более подробные имена, чтобы я мог видеть, для чего они нужны, без поиска в коде.

Кстати, я думаю, что соглашение об именах для них пришло из раннего языка Fortran, где я был первой целочисленной переменной (A - H были числами с плавающей запятой)?

person paxdiablo    schedule 25.09.2008
comment
Это интересный лакомый кусочек истории. Спасибо. - person VirtuosiMedia; 25.09.2008
comment
как говорится, Бог реален, если не объявлено целым числом - person Greg Rogers; 25.09.2008

i вполне допустимо. Однако за семестр я многому научился у своего учителя C ++, который отказался от кода, у которого не было описательного имени для каждой отдельной переменной. Простой акт называния всего описательного заставил меня больше думать о своем коде, и после этого курса я писал лучшие программы, не благодаря изучению C ++, а благодаря тому, что научился все называть. В Code Complete есть несколько хороших слов на ту же тему.

person Clinton Dreisbach    schedule 25.09.2008

i в порядке, но что-то вроде этого - нет:

for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        string s = datarow[i][j].ToString(); // or worse
    }
}

Очень часто программисты случайно меняют местами i и j в коде, особенно если у них плохое зрение или их тема Windows - «хот-дог». Для меня это всегда «запах кода» - это редкость, когда с ним не облажались.

person MusiGenesis    schedule 25.09.2008
comment
Я никогда особо не задумывался о том, почему, но я обычно использую j и k для индексов в матрицах, но я полагаю, что можно перепутать i и j, если у вас плохое зрение. - person Cercerilla; 03.11.2010

i настолько распространен, что приемлем даже для людей, которые любят описательные имена переменных.

Абсолютно неприемлемо (и грех в моей книге) использование i, j или k в любом другом контексте, кроме как целочисленный индекс в цикле .... например.

foreach(Input i in inputs)
{
    Process(i);

}
person Giovanni Galbo    schedule 25.09.2008

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

Думаю, социальная проверка :)

person Ian P    schedule 25.09.2008

Да, на самом деле это предпочтительнее, поскольку любой программист, читающий ваш код, поймет, что это просто итератор.

person Ben Hoffstein    schedule 25.09.2008

В чем смысл использования i вместо более конкретного имени переменной? Чтобы сэкономить 1 секунду или 10 секунд, а может быть, даже 30 секунд размышлений и набора текста?

Какова стоимость использования i? Может ничего. Может быть, код настолько прост, что использовать i можно. Но, может быть, может быть, использование i заставит разработчиков, которые придут к этому коду в будущем, задуматься на мгновение "что я здесь имею в виду?" Им придется подумать: «Это индекс, счетчик, смещение, флаг?» Им придется подумать: «Безопасно ли это изменение, правильно ли я выйду на 1?»

Использование i экономит время и интеллектуальные усилия при написании кода, но может в конечном итоге потребовать дополнительных интеллектуальных усилий в будущем или, возможно, даже привести к непреднамеренному появлению дефектов из-за неправильного понимания кода.

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

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

person Wedge    schedule 25.09.2008

Я использую i для коротких петель.

Причина, по которой все в порядке, заключается в том, что я считаю совершенно неправдоподобным, чтобы кто-то мог увидеть объявление типа итератора с инициализатором, а затем три строки спустя утверждают, что неясно, что представляет собой переменная. Они просто притворяются, потому что решили, что «значимые имена переменных» должны означать «длинные имена переменных».

Причина, по которой я на самом деле это делаю, заключается в том, что я нахожу, что использование чего-то, не связанного с конкретной задачей, и что я буду использовать только в небольшом объеме, избавляет меня от беспокойства о том, что я могу использовать имя, которое вводит в заблуждение, или двусмысленно, или когда-нибудь будет полезно для чего-то еще в более широком масштабе. Причина, по которой это «i», а не «q» или «count», просто условность, заимствованная из математики.

Я не использую i, если:

  • Тело петли не маленькое, или
  • итератор делает что-либо, кроме продвижения (или отступления) от начала диапазона до конца цикла:

i не обязательно должен идти с приращением 1, если приращение является последовательным и четким, и, конечно, может остановиться до конца итерации, но если он когда-либо изменит направление или не будет изменен итерацией цикла (включая дьявольское использование iterator.insertAfter () в прямом цикле), я стараюсь не забывать использовать что-то другое. Это сигнализирует, что «это не просто тривиальная переменная цикла, следовательно, это может быть нетривиальный цикл».

person Steve Jessop    schedule 25.09.2008

Если «что-то более семантическое» - «итератор», то нет причин не использовать i; это хорошо понятная идиома.

person Captain Segfault    schedule 25.09.2008

Я думаю, что я вполне приемлем в ситуациях цикла. Я всегда считал это довольно стандартным и никогда не сталкивался с проблемами интерпретации, когда я использовался в этом случае. Циклы foreach становятся немного сложнее, и я думаю, что это действительно зависит от вашей ситуации. Я редко, если когда-либо, использую i в foreach, только в циклах for, поскольку считаю, что i в этих случаях слишком неинформативен. для foreach я пытаюсь использовать аббревиатуру циклического типа объекта. например:

foreach(DataRow dr in datatable.Rows)
{
    //do stuff to/with datarow dr here
}

в любом случае, только мои 0,02 доллара.

person Community    schedule 25.09.2008

Будет полезно, если вы назовете его чем-то, что описывает то, через что он проходит. Но обычно я просто использую i.

person Matthew Rapati    schedule 25.09.2008

Пока вы используете i для подсчета циклов или часть индекса, который идет от 0 (или 1 в зависимости от PL) до n, я бы сказал, что со мной все в порядке.

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

person Pyrolistical    schedule 25.09.2008

Я должен отметить, что i и j также являются математическими обозначениями для матричных индексов. И обычно вы перебираете массив. Так что в этом есть смысл.

person Jason Baker    schedule 25.09.2008

Если вы временно используете его внутри простого цикла и очевидно, что вы делаете. Тем не менее, нет ли другого короткого слова, которое вы могли бы использовать вместо этого?

i широко известен как итератор цикла, поэтому вы с большей вероятностью запутаете программистов, обслуживающих техобслуживание, если будете использовать его вне цикла, но если вы используете что-то более наглядное (например, filecounter), это сделает код более приятным.

person Dan Udey    schedule 25.09.2008

По-разному. Если вы перебираете какой-то конкретный набор данных, я думаю, что имеет смысл использовать описательное имя. (например, filecounter, как предложил Дэн).

Однако, если вы выполняете произвольный цикл, i приемлемо. Как описал мне один товарищ по работе, i - это соглашение, которое означает, что "эта переменная изменяется только конструкцией цикла for. Если это не так, не используйте i"

person Andrew Edgecombe    schedule 25.09.2008

Использование i, j, k для счетчиков цикла INTEGER восходит к ранним дням FORTRAN.
Лично у меня нет проблем с ними, пока они являются счетчиками INTEGER.
Но потом я вырос на ФОРТРАНЕ!

person DaveF    schedule 25.09.2008

Мне кажется, что концепция использования одной буквы подходит для "простых" циклов, однако я давно научился использовать двойные буквы, и это отлично сработало.

на прошлой неделе я задал аналогичный вопрос, и следующее является частью мой собственный ответ:

// recommended style              ●    // "typical" single-letter style
                                  ●
for (ii=0; ii<10; ++ii) {         ●    for (i=0; i<10; ++i) {
    for (jj=0; jj<10; ++jj) {     ●        for (j=0; j<10; ++j) {
        mm[ii][jj] = ii * jj;     ●             m[i][j] = i * j;
    }                             ●        }
}                                 ●    }
на тот случай, если выгода не сразу очевидна: поиск по коду любой отдельной буквы обнаружит много вещей, которые не то, что вы находясь в поиске. буква i довольно часто встречается в коде, где это не та переменная, которую вы ищете.

Я делаю это уже как минимум 10 лет.

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

person just mike    schedule 25.09.2008
comment
А для людей с редакторами, которые могут искать по разрыву слов, совершенно бессмысленно. - person Jon Ericson; 25.09.2008
comment
Немного оффтопа: зачем в операторе for предварительно инкрементировать переменную цикла? Обычно я вижу POSTINCREMENT вместо преинкремента. - person Andrei Rînea; 04.10.2008
comment
эффективность. это происходит из моего раннего опыта работы с языком C, когда оптимизаторы сборки не были идеальными. если вы выполняете пост-инкремент, выражения сначала оцениваются, затем увеличиваются, а затем снова вычисляются. если вы выполняете предварительное приращение, начальная оценка отсутствует, просто увеличивается, а затем оценивается. - person just mike; 05.10.2008

Я собираюсь пойти против течения и сказать нет.

Для толпы, которая говорит, что «i понимается как итератор», это может быть правдой, но для меня это эквивалент комментариев типа «Присвойте значение 5 переменной Y». Имена переменных, такие как комментарий, должны объяснять, почему / что не как.

Чтобы использовать пример из предыдущего ответа:

for(int i = 0; i < 10; i++)
{
    // i is well known here to be the index
    objectCollection[i].SomeProperty = someValue;
}

Неужели намного сложнее просто использовать такое значимое имя?

for(int objectCollectionIndex = 0; objectCollectionIndex  < 10; objectCollectionIndex ++)
{
    objectCollection[objectCollectionIndex].SomeProperty = someValue;
}

Допустим, имя (заимствованное) имя переменной objectCollection тоже имеет довольно плохое имя.

person JohnFx    schedule 03.11.2010