Страница 2 из 2

Добавлено: 25.02.2008 21:04:09
trifon
В написанном мною юните ncurses проверка на существование тоже производится, в приведенном примере нет, так как к вопросу это не имеет отношения.

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

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

Касательно шаблонов - хороший вариант, но у меня FPC 2.2.0 поэтому
сказать на эту тему ни чего не могу.

Добавлено: 25.02.2008 21:14:00
Alexander
Как можно понять эту строчку ?

Код: Выделить всё

#define getyx(win,y,x)      (y = getcury(win), x = getcurx(win))


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

Или это бред ? Си я не знаю.

Добавлено: 25.02.2008 21:29:06
Максим
trifon
Первый вариант работает, только типы он не проверяет.

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

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

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

В данном случае использование макросов напоминает использование процедур.

Добавлено: 25.02.2008 21:51:39
trifon
Я перепутал, первый вариант как раз рабочий, не работает второй.
Что означает var и как он работает я знаю.
Почему не работает второй ответа не было.
И вообще, все это пустой треп.
Был задан конкретный вопрос, вместо этого гонится какая то пурга, о которой я и сам мог догадаться, задаются вопросы про C.
По существу был только первый ответ.

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

Модераторам: предлагаю закрыть тему.

Добавлено: 25.02.2008 22:07:55
trifon
А зачем ее закрывать?
Может кто то ответ знает.
Наверняка кому то будет интересно, а кому то возможно и пригодится.

Добавлено: 26.02.2008 14:00:06
trifon
Тута решил написать програмку, дабы потестить это

Код: Выделить всё

{$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;


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

Прошу прощения за длинный код, он вообще то не сложный, пускай это будет ответом тем, кто предлагает использовать перегрузку, тем более, что что потребности в этом нет.

Добавлено: 26.02.2008 14:22:07
trifon
И у меня возник вопрос - почему компилятор не выдает хотя бы ворнинга?
А потом при работе программ начинается непонятный полтергейст, который трудно понять.
Короче как я понял
Longint(a) := rec.af; Longint(b) := rec.bf - правильно(по логике)
Smallint(a) := rec.af; Smallint(b) := rec.bf - должно при компиляции выдать или ошибку или ворнинг(также по логике), так как в FPC создание класса с абстрактными методами выдает всего лишь ворниг, то по логике должен быть ворнинг.

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

Что касается макросов в Си - они вообще не имеют отношения к типизации, это тупая подстановка одного выражения вместо другого перед компиляцией. Это _не_ функции, и замена макроса функцией в общем случае может менять смысл программы.
В FPC, кстати, тоже можно использовать макросы, только нужно включить режим {$macros on}.

Добавлено: 02.03.2008 17:52:32
trifon
Короче ни как не правильно, обнаружил еще более интересный эффект

Код: Выделить всё

{$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.
Убил много времени, поко не понял это.

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

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

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

Не типизированными параметрами лучше вобще не пользоваться.