var аргументы процедуры

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

Сообщение trifon » 25.02.2008 22:04:09

В написанном мною юните ncurses проверка на существование тоже производится, в приведенном примере нет, так как к вопросу это не имеет отношения.

Что касается кода на C, аналога var в C нету(в C++ ссылки есть), можно использовать указатели, однако это код усложнит, данный макрос можно легко и удобно использовать с любыми целыми без проблем. Но вообще я оригинальный ncurses не создавал, хотя с макросами там явный перебор, предлагаю написать авторам, что они уроды.

Что касается free pascal, то объяснения данной ошибки я так и не увидел ни в мануале ни здесь, по логике в первом варианте все должно работать(если он скомпилировался без ворнингов).

Касательно шаблонов - хороший вариант, но у меня FPC 2.2.0 поэтому
сказать на эту тему ни чего не могу.
Последний раз редактировалось trifon 25.02.2008 22:21:25, всего редактировалось 1 раз.
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение Alexander » 25.02.2008 22:14:00

Как можно понять эту строчку ?
Код: Выделить всё
#define getyx(win,y,x)      (y = getcury(win), x = getcurx(win))


Предположу:
1. здесь определяется процедура(или что это ?) getyx
2. её аргументы win, y, x
3. если аргументов y, x нет, то вызываются функции
getcury и getcurx для инициализации их значений

Или это бред ? Си я не знаю.
Аватара пользователя
Alexander
энтузиаст
 
Сообщения: 697
Зарегистрирован: 18.12.2005 19:10:00
Откуда: оттуда

Сообщение Максим » 25.02.2008 22:29:06

trifon
Первый вариант работает, только типы он не проверяет.

Как уже было сказано раз десять, здесь желательно использовать перегрузку процедур.

А по поводу ошибки, если вы имеете ввиду ошибку несоответствия типов, всё просто: модификатор var означает передачу параметра по ссылке. Таким образом, его возможно передать как в процедуру, так и из неё. Следовательно, должно быть взаимнооднозначное соответствие типов.

Alexander
1. Это определяется макрос препроцессора, похожий на процедуру.
2. Верно.
3. Аргументы x и y инициализируются макросами getcury и getcurx, которые, в свою очередь, вызывают значения определённых полей записи win.

В данном случае использование макросов напоминает использование процедур.
Аватара пользователя
Максим
энтузиаст
 
Сообщения: 597
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Сообщение trifon » 25.02.2008 22:51:39

Я перепутал, первый вариант как раз рабочий, не работает второй.
Что означает var и как он работает я знаю.
Почему не работает второй ответа не было.
И вообще, все это пустой треп.
Был задан конкретный вопрос, вместо этого гонится какая то пурга, о которой я и сам мог догадаться, задаются вопросы про C.
По существу был только первый ответ.
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение Максим » 25.02.2008 23:02:58

Вы уж определитесь: либо знаете, как работает var и, следовательно, почему возникла ошибка, либо нет :(

Модераторам: предлагаю закрыть тему.
Аватара пользователя
Максим
энтузиаст
 
Сообщения: 597
Зарегистрирован: 27.07.2007 01:51:43
Откуда: Москва

Сообщение trifon » 25.02.2008 23:07:55

А зачем ее закрывать?
Может кто то ответ знает.
Наверняка кому то будет интересно, а кому то возможно и пригодится.
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение trifon » 26.02.2008 15:00:06

Тута решил написать програмку, дабы потестить это
Код: Выделить всё
{$MODE OBJFPC}

type
  trec = record
    af,bf: Smallint;
  end;

procedure getab(rec: trec; var a,b);
begin
  //Smallint(a) := rec.af; Smallint(b) := rec.bf
  Longint(a) := rec.af; Longint(b) := rec.bf
end;

procedure check_byte(tst: trec);
var
  ta: Byte = 0;
  tb: Byte = 0;
begin
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ';');
end;

procedure check_word(tst: trec);
var
  ta: Word = 0;
  tb: Word = 0;
begin
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ' ');

  ta := 65535; tb := 65535;
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ';');
end;

procedure check_sint(tst: trec);
var
  ta: Smallint = 0;
  tb: Smallint = 0;
begin
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ' ');

  ta := -32768; tb := 32767;
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ';');
end;

procedure check_lint(tst: trec);
var
  ta: Longint = 0;
  tb: Longint = 0;
begin
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ' ');

  ta := -32768; tb := 32767;
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ' ');

  ta := -2147483648; tb := 2147483647;
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ';');
end;

procedure check_lword(tst: trec);
var
  ta: Longword = 0;
  tb: Longword = 0;
begin
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ' ');

  ta := -32768; tb := 32767;
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ' ');

  ta := 4294967295; tb := 4294967295;
  getab(tst,ta,tb);
  write((ta = tst.af) AND (tb = tst.bf), ';');
end;

Type
  TCheckt = procedure(tst: trec);

const
  tst: array[0..6] of trec =
                       (
                         (af:0;bf:0),
                         (af:1;bf:3),
                         (af:-3;bf:-1),
                         (af:2047;bf:2047),
                         (af:-2048;bf:-2048),
                         (af:32767;bf:32767),
                         (af:-32768;bf:-32768)
                       );

var
  i: Longint;
  cfn: TCheckt;
begin
  writeln('Byte:');
  cfn := @check_byte;
  for i := 0 to 6 do
    cfn(tst[i]);
  writeln;

  writeln('Word:');
  cfn := @check_word;
  for i := 0 to 6 do
    cfn(tst[i]);
  writeln;

  writeln('Smallint:');
  cfn := @check_sint;
  for i := 0 to 6 do
    cfn(tst[i]);
  writeln;

  writeln('Longint:');
  cfn := @check_lint;
  for i := 0 to 6 do
    cfn(tst[i]);
  writeln;

  writeln('Longword:');
  cfn := @check_word;
  for i := 0 to 6 do
    cfn(tst[i]);
  writeln;
end.


Ее вывод
Код: Выделить всё
Byte:
TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;
Word:
TRUE TRUE;TRUE TRUE;FALSE FALSE;TRUE TRUE;FALSE FALSE;TRUE TRUE;FALSE FALSE;
Smallint:
TRUE TRUE;TRUE TRUE;TRUE TRUE;TRUE TRUE;TRUE TRUE;TRUE TRUE;TRUE TRUE;
Longint:
TRUE TRUE TRUE;TRUE TRUE TRUE;TRUE TRUE TRUE;TRUE TRUE TRUE;TRUE TRUE TRUE;TRUE TRUE TRUE;TRUE TRUE TRUE;
Longword:
TRUE TRUE;TRUE TRUE;FALSE FALSE;TRUE TRUE;FALSE FALSE;TRUE TRUE;FALSE FALSE;

Вроде все правильно, ошибки если record поля больше тестируемых переменных, а также если поля отрицательные, в то время как переменные беззнаковые.

если в коде поменять:
procedure getab(rec: trec; var a,b);
begin
//Smallint(a) := rec.af; Smallint(b) := rec.bf
Longint(a) := rec.af; Longint(b) := rec.bf
end;

на
procedure getab(rec: trec; var a,b);
begin
Smallint(a) := rec.af; Smallint(b) := rec.bf
//Longint(a) := rec.af; Longint(b) := rec.bf
end;


Получаются явные ошибки, если переменные инициализированы не нулевыми значениями, то есть остается мусор.

Прошу прощения за длинный код, он вообще то не сложный, пускай это будет ответом тем, кто предлагает использовать перегрузку, тем более, что что потребности в этом нет.
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение trifon » 26.02.2008 15:22:07

И у меня возник вопрос - почему компилятор не выдает хотя бы ворнинга?
А потом при работе программ начинается непонятный полтергейст, который трудно понять.
Короче как я понял
Longint(a) := rec.af; Longint(b) := rec.bf - правильно(по логике)
Smallint(a) := rec.af; Smallint(b) := rec.bf - должно при компиляции выдать или ошибку или ворнинг(также по логике), так как в FPC создание класса с абстрактными методами выдает всего лишь ворниг, то по логике должен быть ворнинг.
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение Sergei I. Gorelkin » 27.02.2008 13:58:11

В записи SmallInt(a) := rec.af обе стороны имеют тип smallint, левая - потому что ты так в явном виде указал, правая - потому что компилятор об этом знает из объявления переменной rec. Если при таком раскладе компилятор начнет выдавать варнинги, то это будет происходить вообще при каждом присваивании.

Что касается макросов в Си - они вообще не имеют отношения к типизации, это тупая подстановка одного выражения вместо другого перед компиляцией. Это _не_ функции, и замена макроса функцией в общем случае может менять смысл программы.
В FPC, кстати, тоже можно использовать макросы, только нужно включить режим {$macros on}.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1395
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Сообщение trifon » 02.03.2008 18:52:32

Короче ни как не правильно, обнаружил еще более интересный эффект
Код: Выделить всё
{$MODE OBJFPC}

type
   trec = record
     af,bf,cf,df: Smallint;
   end;

procedure getab(rec: trec; var a,b);
begin
   Longint(a) := rec.af; Longint(b) := rec.bf
end;

var
   tstr1: trec = (af:1;bf:3;cf:-32768;df:-32768);
   tstr2: trec = (af:-32768;bf:-32768;cf:-32768;df:-32768);
begin
   with tstr2 do
   begin
     writeln('af:', af,'  bf:',bf,'  cf:', cf,' df:',df);
     getab(tstr1,af,bf);
     writeln('af:', af,'  bf:',bf,'  cf:', cf,' df:',df);
   end;
end.


результат
af:-32768 bf:-32768 cf:-32768 df:-32768
af:1 bf:3 cf:0 df:-32768

Здесь из tstr1 берутся поля af bf и записываются в af bf поля tstr2,
помимо записи полей af bf, в cf оказывается 0.
Убил много времени, поко не понял это.
trifon
постоялец
 
Сообщения: 135
Зарегистрирован: 24.12.2006 12:08:35

Сообщение alexs » 02.03.2008 19:35:33

Что ты хочеш с таким кодом получить?
фактически ты передёаш не типизированны указатель на участок памяти. В основной процедуре ты подразумеваеш что этот указатель указвает на участок в котором хранится 4 2-х байтных числа
в процедуре ты работаеш с этими указатеолями как с указателями на 4-х байтное число - соответсвенно получаеш бред.

ты ещё попробуй порядок присваивания поменять - сначала b затем a.

Используй нормальные вар-параметры с описанием их типа.

Не типизированными параметрами лучше вобще не пользоваться.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Пред.

Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6

Рейтинг@Mail.ru
cron