#c
// reverse the number so that the 1's digit is first for (i = 0; i * 2 < *d_a - 1; i++) { c = a[i], a[i] = a[*d_a - i - 1], a[*d_a - i - 1] = c; } Наткнулся на такой код, и не понятно,почему всё написано специально в строчку и через запятую? Зачем так писать?
Ответы
Ответ 1
Язык С испокон веков поддерживает две парадигмы программирования: программирование на языке инструкций (statements) и программирование на языке выражений (expressions). Один и тот же код во многих случаях можно записать и на языке инструкций, и на языке выражений. На языке инструкций мы реализуем дейкстровскую концепцию последовательного выполнения путем простого последовательного перечисления инструкций. Концепция ветвления реализуется через инструкции if и switch. Концепция итерирования реализуется через for, while и т.п На языке выражений мы реализуем концепцию последовательного выполнения путем перечисления подвыражений с оператором "запятая" в качестве "разделителя". Концепция ветвления реализуется через оператор ?:. Концепция итерирования не реализуется (разве что через рекурсию, которая требует обращения к языку инструкций). Операторы && и || реализуют "гибридные" концепции последовательного выполнения + ветвления. Так что это и есть ответ на вопрос о роли оператора "запятая" - это бинарный оператор, который обеспечивает последовательное изолированное вычисление двух подвыражений: сначала левого, а потом правого. При этом результатом всего выражения является результат правого операнда оператора "запятая". Последнее автоматически означает, что в выражении <подвыражение_1>, <подвыражение_2>, ..., <подвыражение_N> результаты подвыражений от 1-го до N-1-го игнорируются. Если эти подвыражения не имеют побочных эффектов, то они фактически "ничего не делают" вообще, ни на что не влияют и могут быть спокойно удалены из кода. Зачем оператор "запятая" применен в вашем примере - сказать трудно. Там никакой необходимости в применении именно оператора "запятая" не видно. Скорее всего это особенность стилистических предпочтений автора кода. Запись в одну строчку, как и запись одним выражением, обычно затрудняет пошаговую отладку кода. Одно из [полу-]идиоматических чисто стилистических применений оператора "запятая" проистекает из его популярности в заголовках цикла for. Например, некий цикл может выглядеть так int array[N]; ... int *ptr = array; for (unsigned n = N; n > 0; --n, ++ptr) ... Если по какой-то причине нам понадобится "досрочно" перейти к следующему элементу (или даже вообще перенести последнюю часть заголовка for внутрь тела цикла), то такой переход могут записывать именно через оператор "запятая", чтобы подчеркнуть тот факт, что это фактически вынесенная сюда часть заголовка цикла for (unsigned n = N; n > 0; /* --n, ++ptr */) { ... if (...) --n, ++ptr; ... --n, ++ptr; }Ответ 2
Оператор запятая (только не надо путать с перечислением аргументов или объявлением переменных через запятую) предназначен для последовательного выполнения нескольких действий. В данном случае, скорее всего, он использовался для того, чтобы не ставить фигурные скобки (впрочем, их всё равно кто-то добавил). Ну либо просто для того, чтобы подчеркнуть целостность действия в этой строчке (своп двух переменных), а не разбивать его на 3 независимых оператора.Ответ 3
Оператор «запятая» используется для связки нескольких выражений. Левая сторона оператора «запятая» всегда вычисляется как void (то есть не выдающее значения). Это означает, что значение выражения, находящегося с правой стороны, станет значением разделенного запятыми выражения. Например: х = (у = 3, у + 1); Об операторе «запятая» следует думать как об обычном слове «и» в нормальном русском языке, когда оно используется в выражении «сделай это, и это, и это». http://www.c-cpp.ru/books/operator-zapyataya https://msdn.microsoft.com/ru-ru/library/zs06xbxh.aspx http://proguroki.ru/urok4/urok-4-8-operatsiya-zapyataya
Комментариев нет:
Отправить комментарий