|
Программирование >> Перегруженные имена функций и идентификаторы
Почему вот такой код: a[i] = не работает? Подвыражение i++ приводит к побочному эффекту - значение i изменяется, что приводит к неопределенности, если i уже встречается в том же выражении. Пропустив код int i = 7; printf( %d\n , i++ * через свой компилятор, я получил на выходе 49. А разве, независимо от порядка вычислений, результат не должен быть равен 56? Хотя при использовании постфиксной формы операторов ++ и -- увеличение и уменьшение выполняется после того как первоначальное значение использовано, тайный смысл слова после часто понимается неверно. Не гарантируется, что увеличение или уменьшение будет выполнено немедленно после использования первоначального значения перед тем как будет вычислена любая другая часть выражения. Просто гарантируется, что изменение будет произведено в какой-то момент до окончания вычисления (перед следующей точкой последовательности в терминах ANSI C). В приведенном примере компилятор умножил предыдущее значение само на себя и затем дважды увеличил i на 1. Поведение кода, содержащего многочисленные двусмысленные побочные эффекты не определено. Даже не пытайтесь выяснить, как ваш компилятор все это делает (в противоположность неумным упражнениям во многих книгах по С). Я экспериментировал с кодом: int i = 2; i = i++; Некоторые компиляторы выдавали i=2, некоторые 3, но один выдал 4. Я знаю, что поведение не определено, но как можно получить 4? Неопределенное (undefined) поведение означает, что может случиться все что угодно. Люди твердят, что поведение не определено, а я попробовал ANSI-компилятор и получил то, что ожидал Компилятор делает все, что ему заблагорассудится, когда встречается с неопределенным поведением (до некоторой степени это относится и к случаю зависимого от реализации и неописанного поведения). В частности, он может делать то, что вы ожидаете. Неблагоразумно, однако, полагаться на это. Могу я использовать круглые скобки, чтобы обеспечить нужный мне порядок вычислений? Если нет, то разве приоритет операторов не обеспечивает этого? Круглые скобки, как и приоритет операторов обеспечивают лишь частичный порядок при вычислении выражений. Рассмотрим выражение: f() + g() * h() . Хотя известно, что умножение будет выполнено раньше сложения, нельзя ничего сказать о том, какая из трех функций будет вызвана первой. Тогда как насчет операторов &&, и запятой? Я имею в виду код типа if((c = getchar()) == EOF c == An) Для этих операторов, как и дя оператора ?: существует специальное исключение; каждый из них подразумевает определенный порядок вычислений, т.е. гарантируется вычисление слева-направо. Если я не использую значение выражения, то как я должен увеличивать переменную i: так: ++i или так: Применение той или иной формы сказывается только на значении выражения, обе формы полностью эквивалентны, когда требуются только их побочные эффекты. Почему неправильно работает код: int a = 1000, b = 1000; long int c = a * b; Согласно общим правилам преобразования типов языка Си, умножение выполняется с использованием целочисленной арифметики, и результат может привести к переполнению и/или усечен до того как будет присвоен стоящей слева переменной типа long int. Используйте явное приведение типов, чтобы включить арифметику длинных целых: long int c = (long int)a * b; Заметьте, что код (long int)(a * b) не приведет к желаемому результату. Что такое стандарт ANSI C? В 1983 году Американский институт национальных стандартов (ANSI) учредив комитет X3J11, чтобы разработать стандарт языка Си. После длительной и трудной работы, включающей выпуск нескольких публичных отчетов, работа комитета завершилась 14 декабря 1989 г.созданием стандарта ANS X3.159-1989. Стандарт б1л опубликован весной 1990 г. В большинстве случаев ANSI C узаконил уже существующую практику и сделал несколько заимствований из С++ (наиболее важное - введение прототипов функций). Б1ла также добавлена поддержка национальных наборов символов (включая подвергшиеся наибольшим нападкам трехзнаковые последовательности). Стандарт ANSI C формализовал также стандартную библиотеку. Опубликованный стандарт включает Комментарии ( Ratlonale ), в которых объясняются многие решения и обсуждаются многие тонкие вопросы, включая несколько затронутых здесь. ( Комментарии не входят в стандарт ANSI X3.159-1989, они приводятся в качестве дополнительной информации.) Стандарт ANSI был принят в качестве международного стандарта ISO/IEC 9899:1990, хотя нумерация разделов иная (разделы 2 - 4 стандарта ANSI соответствуют разделам 5 - 7 стандарта ISO), раздел Комментарии не был включен. Как получить копию Стандарта? ANSI X3.159 б1л официально заменен стандартом ISO 9899. Копию стандарта можно получить по адресу: American National Standards Institute 11 W. 42nd St., 13th floor New York, NY 10036 USA (+1) 212 642 4900 Global Engineering Documents 2805 McGaw Avenue Irvine, CA 92714 USA (+1) 714 261 1455 (800) 854 7179 (U.S. & Canada) В других странах свяжитесь с местным комитетом по стандартам или обратитесь в Национальный Комитет по Стандартам в Женеве: ISO Sales Case Postale 56 CH-1211 Geneve 20
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |