Я наткнулся на эту программу через ответ quora
#include<stdio.h>
int main() {
printf("%d\n", ( { int n; scanf("%d", &n); n*n; } ));
return 0;
}
Мне было интересно, как это работает, и если это соответствует стандарту?
Я наткнулся на эту программу через ответ quora
#include<stdio.h>
int main() {
printf("%d\n", ( { int n; scanf("%d", &n); n*n; } ));
return 0;
}
Мне было интересно, как это работает, и если это соответствует стандарту?
Этот код использует функцию "GNU C", называемую выражением оператора, в которой заключенный в скобки составной оператор может использоваться как выражение, тип и значение которого соответствуют результату последнего оператора в составной инструкции. Это не синтаксически допустимая C, а функция GCC (также принятая некоторыми другими компиляторами), которая была добавлена предположительно потому, что она считалась важной для написания макросов, которые не оценивают свои аргументы более одного раза.
Вы должны знать, что это такое и что он делает, если вы столкнулись с ним в коде, который вы должны прочитать, но я бы не стал его использовать самостоятельно. Это запутанное, ненужное и нестандартное. То же самое можно добиться почти всегда с помощью статических встроенных функций.
Я не верю, что это сработает... n
имеет локальную область в фигурных скобках... когда вы выходите из фигурных скобок, n
становится undefined, хотя я полагаю, что может все еще существуют где-то в стеке и может работать. Он просил о проблемах внедрения, и я гарантирую, что это зависит от реализации.
Одна вещь, которую я могу вам сказать, это то, что любой, кто работает для меня, который написал это, будет прочитан акт беспорядков.
Это работает. Я не получаю никаких предупреждений от gcc, поэтому я полагаю, что он соответствует стандарту.
Магия - это замыкание:
{ int n; scanf("%d", &n); n*n; }
Этот самородок сканирует целое число с консоли (без проверки ошибок) и разбивает его на квадрат, возвращая квадрат числа. В древних реализациях C возвращается последнее число в стеке. n*n
помещает номер в стек.
Это значение передается printf:
printf("%d\n", <scanned>);
Итак, чтобы ответить на ваши вопросы: Да, это работает. Да, это "стандарт" (в той степени, в которой кто-то полностью соответствует стандарту). Нет, это не очень хорошая практика. Это хороший пример того, что я, вызвав крик коленного сустава, называю "любовным письмом компилятора", разработанным в основном для того, чтобы показать, насколько умный программист, не обязательно решить проблему или быть эффективным.