adfun.ru
| |
BIGLIB |
| большущая библиотека (9812 книг), можно не только прочитать но и скачать бесплатно |
|
| |
ФАНТАСТИКА |
| фентези,
фантастика, фантастические повести |
|
| |
ФИЛОСОФИЯ |
книги, которые заставляют
задуматься над окружающим тебя миром.
|
|
| |
МЕДИЦИНА |
медицинские книги,
методички,
народные лечебники |
|
| |
КУЛИНАРИЯ |
рецепты
тортов, консервирование,
все о спиртных
напитках. |
|
| |
СТИХИ |
| стихи популярных
и не очень авторов |
|
| |
ТВОРЧЕСТВО |
| народное творчество,
стихи, песни и т.д. |
|
| |
ЮМОР |
| анекдоты, приколы,
смешные истории |
|
| |
ЭРОТИКА |
| эротические рассказы,
книги о технике секса,
кама-сутра и др. |
|
|
| |
 |
размера:
int i = OXFFFE;
long l;
l = i;
if (l & OX800000000) {
... /* это будет выполнено */
}
Один из моментов в Си, который может привести к неприятнос-
тям, состоит в том, что вы не знаете о последствиях. Язык Си поз-
воляет свободно использовать присваивание одной целочисленной
скалярной величины (char, int и т.д.) другой, знак (положительный
TDeb 3.0 #2-3 = 128 =
или отрицательный) сохраняется в переменной большего размера,
причем бит знака (старший бит) распространяется на всю старшую
часть большего скалярного значения. Например, значение типа int -
2 (Oxfffe) становится значением типа long -2 (oxfffffffe).
TDeb 3.0 #2-3 = 129 =
Помните об усечении
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Данный пример противоположен примеру предыдущего раздела:
int i = 1;
long l = OX10000;
l = i;
if (i > 0) {
... /* это не будет выполнено */
}
Здесь присваивание i значения 1 приводит к усечению старших
16 бит 1, при этом в i остается значение 0.
Использование точки с запятой
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Следующий фрагмент программы на первый взгляд выглядит прек-
расно:
for (x = 0; x < 10; x++);
{
... /* будет выполнено 1 раз */
}
Почему фрагмент в фигурных скобках будет выполнен только 1
раз? При ближайшем рассмотрении оказывается, что в конце выраже-
ния for содержится точка с запятой (;). Это труднообнаруживаемая
ошибка приводит к тому, что цикл выполниться 10 раз, не реализуя
никаких действий. Последующий блок выполниться только 1 раз. Это
неприятная ошибка, так как ее нельзя обнаружить с помощью обычных
методов проверки и идентификации блоков программы.
Макрокоманды с побочными эффектами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Следующая проблема может заставить вас никогда не использо-
вать макрокоманды #define:
#define toupper(c) 'a'<= (c)&&(c)<='z' ? (c)-'a'-'A': (c)
char c, *p;
c = toupper(*p++);
Здесь p увеличивается 2 или 3 раза, в зависимости от регист-
ра символа (строчная или прописная буква). Такую ошибку очень
трудно найти, так как побочный эффект скрыт внутри макроопределе-
ния.
Повторение имен локальных динамических переменных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
TDeb 3.0 #2-3 = 130 =
Следующую ошибку также трудно обнаружить:
myfunc()
{
int n;
for (n=5; n >= 0; n--)
{
int n = 10;
...
if (n == 0)
{
... /* никогда не будет выполняться */
}
}
}
}
Здесь имя динамической локальной переменной повторно исполь-
зуется во внутреннем блоке, скрывая доступ к переменной внешнего
блока. При таком повторном использовании имен переменных нужно
соблюдать аккуратность. Сделать такую ошибку гораздо легче, чем
может вам показаться, так как большинство программистов использу-
ют в качестве имени счетчика ограниченный набор имен (i, n и
т.д.).
Неправильное использование динамических локальных переменных
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Рассмотрим пример функции:
int *divide_by_3(int n)
{
int i;
i = n / 3;
return(&i);
}
Смысл данной функции состоит в возврате указателя на резуль-
тат. Ошибка состоит в том, что к тому моменту, когда функция
возвращает управление, динамическая локальная переменная стано-
вится недействительной и будет вероятно заполнена другими данными
в стеке.
Функция возвращает неопределенное значение
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Если вы не завершаете функцию ключевым словом return, за ко-
торым следует выражение, то будет возвращаться неопределенное
значение. Например:
char *first_capital_letter(char *p)
TDeb 3.0 #2-3 = 131 =
{
while (*p)
{
if ('A' <= *p && *p <= 'Z)
return(p);
p++;
}
}
Если в строке не содержится буква в верхнем регистре, то
возвращается случайное значение ("мусор"). В качестве последней
строки данной функции нужно использовать оператор return(0).
Неправильное использование ключевого слова break
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Ключевое слово break выполняет выход только из одного уровня
операторов do, for, switch или while:
for (...)
{
while (...)
{
if (...)
break; /* хотим выйти из цикла */
}
}
Здесь break выполняет выход только из цикла while. Это один
из немногих случаев, когда предпочтительнее использовать опера-
тор goto.
Код, не приводящий к результату
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Иногда может встречаться прекрасно компилируемый код, кото-
рый не приводит ни к какому результату:
a + b;
Правильным вариантом этой строки будет:
a += b
TDeb 3.0 #2-3 = 132 =
Ошибки, специфические для Паскаля
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Поскольку в Паскале имеются средства, обеспечивающие строгую
проверку типов и проверку ошибок, то этот язык мало способствует
специфическим для него ошибкам. Однако, поскольку Турбо Паскаль
предоставляет вам возможность "выключать" проверку ошибок, вы мо-
жете внести ошибки, которые в противном случае не возникли бы.
Между тем даже в Паскале есть способы этого избежать.
Инициализированные переменные
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Турбо Паскаль не инициализирует переменные автоматически. Вы
|
adfun.ru
|
|
|
|