Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Функция для замены местами переменных любого типа / 23 сообщений из 23, страница 1 из 1
19.05.2017, 07:51:45
    #39455782
delphiprog
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Можно ли на Delphi сделать универсальную функцию для того, чтобы поменять местами 2 переменные любого типа данных (за исключением объектов, возможно)? Такой код не хочет работать:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure swap(a, b: pointer);
var c: pointer;
begin
    c^ := a^;
    a^ := b^;
    b^ := c^;
end;
...
Рейтинг: 0 / 0
19.05.2017, 08:03:08
    #39455786
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Код: pascal
1.
procedure swap(a, b: Variant);
...
Рейтинг: 0 / 0
19.05.2017, 08:34:05
    #39455799
Dmitry Arefiev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
type
  Swap = class
    class procedure It<T>(var a, b: T); static;
  end;

class procedure Swap.It<T>(var a, b: T);
var
  c: T;
begin
  c := a;
  a := b;
  b := c;
end;

var
  e1, e2: Double;
...
  Swap.It(e1, e2);
...
Рейтинг: 0 / 0
19.05.2017, 10:42:41
    #39455904
Maxim Rusov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Чет не работает.

Только если так:

Swap.It<Double>(A1, A2);
...
Рейтинг: 0 / 0
19.05.2017, 10:44:05
    #39455906
Dimonka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Dmitry Arefiev
Код: pascal
1.
2.
...
  Swap.It(e1, e2);


А разве не надо тип указывать?
Код: pascal
1.
Swap<Double>.It(e1, e2);
...
Рейтинг: 0 / 0
19.05.2017, 10:49:04
    #39455911
Квейд
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
DimaBr
Код: pascal
1.
procedure swap(a, b: Variant);

этот вызов не свопнет две внешние переменные
...
Рейтинг: 0 / 0
19.05.2017, 12:25:33
    #39456022
Dmitry Arefiev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
DimonkaА разве не надо тип указывать?
Код: pascal
1.
Swap<Double>.It(e1, e2);


Зависит от версии RAD Studio ...
...
Рейтинг: 0 / 0
19.05.2017, 12:54:02
    #39456056
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Код: pascal
1.
procedure swap(var a, b: Variant);
...
Рейтинг: 0 / 0
19.05.2017, 13:02:32
    #39456063
Квейд
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
DimaBr
Код: pascal
1.
procedure swap(var a, b: Variant);

Ага, только не забываем, что types of actual and formal var parameters must be identical, то есть не получится свопнуть невариантные переменные.
...
Рейтинг: 0 / 0
19.05.2017, 13:21:53
    #39456093
SimplTsar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
procedure EXCHANGE(var v1,v2; size: LongWord); assembler; register;
asm
{     ->EAX     Pointer to v1    }
{       EDX     Pointer to v2    }
{       ECX     size             }

        PUSH    ESI
        PUSH    EDI
        PUSH    EBX

        MOV     ESI,EAX         { ESI - адрес v1 }
        MOV     EDI,EDX         { EDI - адрес v2 }
        MOV     EDX,ECX         { EDX - количество обмениваемых данных }

        SAR     ECX,2           { пересчет в двойный слова size DIV 4  }
        JZ      @@smal          { размер < 4 }

        CLD                     { автоинкремент }
        MOV     EBX,-4          { для адресации }
@@loop1:
        MOV     EAX,DWORD PTR [EDI]      { 4al:=v1[j] }
        MOVSD                            { v2[j]:=v1[j], j:=j+4, i:=i+4 }
        MOV     DWORD PTR [ESI][EBX],EAX { v1[i-4]:=4al }
        LOOP    @@loop1

@@smal:
        MOV     ECX,EDX         { опредлеление оставшихся }
        AND     ECX,03H         { байт }
        JZ      @@exit          { нечего обменивать }
        MOV     EBX,-1
@@loop2:
        MOV     AL,BYTE PTR [EDI]       { al:=v1[j] }
        MOVSB                           { v2[j]:=v1[j], j:=j+1, i:=i+1 }
        MOV     BYTE PTR [ESI][EBX],AL  { v1[i-1]:=al }
        LOOP    @@loop2
@@exit:
        POP     EBX
        POP     EDI
        POP     ESI
end; { EXCHANGE }



PS Кнопка src почему-то не работает
...
Рейтинг: 0 / 0
19.05.2017, 13:52:09
    #39456124
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
procedure Swap(var A,B; AType: byte);
var Z: Variant;
begin
  case AType of
    vtInteger : begin
      Z := integer(A);
      integer(A) := integer(B);
      integer(B) := Z;
    end;
    vtString : begin
      Z := string(A);
      string(A) := string(B);
      string(B) := Z;
    end;

  end;
end;


procedure TForm1.FormClick(Sender: TObject);
var A,B: integer;
    C,D: string;
begin
  A := 1; B := 2;
  C := 'A'; D := 'B';
  Swap(A,B,vtInteger);
  Swap(C,D,vtString);
  ShowMessage(Format('%d %d %s %s',[A,B,C,D]));
end;
...
Рейтинг: 0 / 0
19.05.2017, 14:19:48
    #39456149
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Dmitry ArefievЗависит от версии RAD Studio ...Круто! А когда сделали автоматический вывод типа?
...
Рейтинг: 0 / 0
19.05.2017, 14:25:15
    #39456156
Гаджимурадов Рустам
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
ОФФSimplTsarPS Кнопка src почему-то не работаетКакая-то ошибка выдаётся?
...
Рейтинг: 0 / 0
19.05.2017, 14:26:23
    #39456157
errorsoft
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Dmitry ArefievDimonkaА разве не надо тип указывать?
Код: pascal
1.
Swap<Double>.It(e1, e2);


Зависит от версии RAD Studio ...

А вот здесь поподробнее...)
...
Рейтинг: 0 / 0
19.05.2017, 14:35:10
    #39456170
SimplTsar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Гаджимурадов РустамОФФSimplTsarPS Кнопка src почему-то не работаетКакая-то ошибка выдаётся?

Ошибка не выдаётся. Теги не добавляются. Проверял на "Konqueror - 4.14.8" и "Firefox - 50.1.0"
...
Рейтинг: 0 / 0
19.05.2017, 14:43:54
    #39456181
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Ошибка не выдаётся. Теги не добавляются. Проверял на "Konqueror - 4.14.8" и "Firefox - 50.1.0"
А что религия не позволяет написать тег вручную ? Или не барское это дело :
...
Рейтинг: 0 / 0
19.05.2017, 15:10:08
    #39456220
SimplTsar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
DimaBrА что религия не позволяет написать тег вручную ? Или не барское это дело :
Если знать какой - то никаких проблем. Но, к сожалению, мой "хрустальный шар" в ремонте :)
...
Рейтинг: 0 / 0
19.05.2017, 16:22:09
    #39456298
Гаджимурадов Рустам
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
SimplTsar> Ошибка не выдаётся. Теги не добавляются.
SimplTsar> Проверял на "Konqueror - 4.14.8" и "Firefox - 50.1.0"

Странно. Про первый не знаю, а в 50-м FF точно работало.
Сообщите, пожалуйста, все подробности (включая ОС) в
тех.разделе: http://sql.ru/forum/sqlru
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
19.05.2017, 17:04:10
    #39456335
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
_Vasilisk_Круто! А когда сделали автоматический вывод типа?
Появилось в XE8.
errorsoftА вот здесь поподробнее...)
http://docwiki.embarcadero.com/RADStudio/XE8/en/Declaring_Generics#Parameterized_Methods
...
Рейтинг: 0 / 0
19.05.2017, 19:28:16
    #39456450
Guest2013
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Dmitry Arefiev
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
type
  Swap = class
    class procedure It<T>(var a, b: T); static;
  end;

class procedure Swap.It<T>(var a, b: T);
var
  c: T;
begin
  c := a;
  a := b;
  b := c;
end;

var
  e1, e2: Double;
...
  Swap.It(e1, e2);




а если в качестве парметра Record, процедурный тип с параметрами?
...
Рейтинг: 0 / 0
19.05.2017, 19:41:00
    #39456453
Dimonka
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
Один из вариантов:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure Swap(var A, B; Length: integer);
var
  Temp: TBytes;
begin
  SetLength(Temp, Length);
  Move(A, Temp[0], Length);
  Move(B, A, Length);
  Move(Temp[0], B, Length);
end;

  I := 1;
  K := 2;
  Swap(I, K, SizeOf(I));


Правда без типизации..
...
Рейтинг: 0 / 0
19.05.2017, 20:37:22
    #39456486
Dmitry Arefiev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
DimonkaОдин из вариантов
* Работает пока типы не требуют магию компилятора
* SizeOf однажды заставит ошибиться
* 3 * Move = тормоза
А казалось бы ...
...
Рейтинг: 0 / 0
19.05.2017, 21:15:34
    #39456496
Bred eFeM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Функция для замены местами переменных любого типа
* SetLength(Temp, Length); = Тормоза )

Dmitry Arefiev* Работает пока типы не требуют магию компилятора например ?
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Функция для замены местами переменных любого типа / 23 сообщений из 23, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]