 |
файла (имя которого вводится в командной строке) на экран.
Турбо Паскаль Турбо Си
----------------------------------------------------------------
program DumpIt; # include
var main(int argc,char *argv[])
F :Text; {
Ch :Char; FILE *f;
begin int ch;
Assign(F,ParamStr(1));
{SI-}Reset(F);{SI+} f=fopen(argv[1],"r");
if IOResult<>0 then begin if (f==NULL){
Writeln ('Cannot open ',ParamStr(1)); printf("Cannot
open %s\n",argv[1]);
Halt(1); return(1);
end; }
While not EOF(F) do begin
Read(F,Ch); while((ch=getc(f))!=DCF)
Write (Ch) putchar(ch);
end;
Close (F) fclose(f);
end. }
-----------------------------------------------------------------
- 169,170 -
Общие ошибки Паскаль программистов при работе на Си.
-----------------------------------------------------------------
Значительная схожесть языков Паскаль и Си делает некоторые
ошибки очень распространенными. Далее приведем наиболее типичные
ошибки, которые вам необходимо избежать. Эти ошибки Паскаль прог-
раммисту очень трудно заметить, а компилятор их может не обнару-
жить. (Некоторые общие ошибки также рассматриваются в главе 7.)
Ошибка #1: Присваивание и сравнение.
-----------------------------------------------------------------
В Паскале A = B - булево выражение A равно B, которое
возвращает значение true или false. В Си A = B - присваивание: A
получает значение B; однако (и это существенно для понимания),
это выражение также возвращает значение равное B (которое было
присвоено A). Для Паскаль программиста характерен такой оператор:
if (A=B) <оператор>;
Этот оператор разрешен в Си и выполнится так:
# значение B присвоится A,
# выражение A = B возвратит значение B,
# если это значение ненулевое (в Си это true), <оператор>
будет выполнен.
То, что вы реально хотели написать, будет
if (A==B) <оператор>;
который сделает то, что вам надо: если A и B равны, <опера-
тор> выполнится. Запомните: в Си сравнение на равенство это два
знака равенства (==), а не один (=). Один знак равенства в Си это
операция присвоения.
- 171,172 -
Ошибка #2: Забывание о передаче адреса
(особенно, при использовании scanf).
-----------------------------------------------------------------
Как мы отмечали, Си позволяет вам передавать параметры функ-
ции только по значению; если вы хотите передать параметр по адре-
су, вам необходимо непосредственно указать этот адрес. Допустим
вы используете функцию swap, которая была описана в этой главе.
Вы можете допустить ошибку при ее вызове так: swap(q,r), где q и
r имеют тип float. В этом случае swap возьмет значения q и r, ин-
терпретирует их как адрес, а затем поменяет местами значения, на-
ходящиеся по этим адресам.
Как избежать такой ошибки? Лучший путь это использование
прототипов функций. При этом Турбо Си сделает соответсвующую про-
верку при компиляции. Для swap вы можете ввести следующий прото-
тип где-нибудь возле начала вашего исходного файла:
void swap (float *x, float *y);
Теперь, если вы прокомпилируете вашу программу с оператором
swap(q,r), вы получите ошибку, сообщающую, что вы имеете несоот-
ветствие типов при вызове swap.
Ошибка #3: пропуск скобок при вызове функции.
-----------------------------------------------------------------
В Паскале, процедура, не имеющая параметров, вызывается
просто по имени:
AnyProcedure;
i := AnyFunction;
В Си, название функции, если даже нет параметров, должно
всегда содержать открытые и закрытые скобки. Легко ошибиться так:
AnyFunction; /*Нет никакого действия*/
i = AnyFunction; /*Присвоение i адреса AnyFunction */
когда вы действительно хотели:
AnyFunction(); /*Вызвать AnyFunction*/
- 173,174 -
i = AnyFunction(); /*Вызвать AnyFunction, присвоить
результат i */
Ошибка #4: предупреждающие сообщения.
-----------------------------------------------------------------
В добавление к основным ошибочным сообщениям, Турбо Си также
выдает предостережения о не фатальных ошибках. Используя некор-
ректную функцию вызова из предшествующего примера, Турбо Си может
выдать следующие предостережения:
Warning test.c 5: Code has no effect in function main
(код не исполняется в основной функции)
Warning test.c 6: Non-portable pointer assigment in
function main
(в основной функции присваивается не мобильный
указатель)
Оба оператора действительно законны, и так как ошибки не
имели место, может быть создан файл .OBJ. Остерегайтесь! Эти типы
предупреждений будут всегда при фатальных ошибках. Не относитесь
к предостережениям легкомысленно.
Ошибка #5: индексация в многомерных массивах.
-----------------------------------------------------------------
Предположим, вы имеете двумерный массив, названный matrix, и
хотите сослаться на ячейку памяти (i,j). Как программист на Пас-
кале, вы склоны записать это следующим образом:
x = matrix [i,j];
Это вполне возможно, однако не делайте так.
В Си это означает серию выражений, отделенных запятыми; в
этом случае, полное выражение берет величину из последнего выра-
жения, так предшествующий оператор является эквивалентом
x = matrix[j];
- 175,176 -
Это не то, что вы хотели, но это законченный оператор в Си.
Все, что вы получите, это предостережение, так как Си думает, что
вы пробуете присвоить x адрес matrix [j], то есть j-той строки. В
Си вы должны явно индексировать каждый массив. Так вам надо напи-
сать
x = matrix[i] [j];
Памятка. Для многомерного массива каждый индекс заключается
в отдельные скобки.
Ошибка #6: Забывание о различиях между символьными
 |
|