[autolisp] Передача в функцию по ссылке
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > [autolisp] Передача в функцию по ссылке

[autolisp] Передача в функцию по ссылке

Ответ
Поиск в этой теме
Непрочитано 08.03.2012, 11:38 #1
[autolisp] Передача в функцию по ссылке
kriolog
 
Регистрация: 14.11.2010
Сообщений: 25

Есть большой список и функция, его обрабатывающая и изменяющая. Можно обойтись без копирования списка при передаче его в функцию?
И, пользуясь случаем, есть ли способ заменить элемент в списке по номеру (аналог nth)?
Просмотров: 2912
 
Непрочитано 08.03.2012, 11:44
#2
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,404


Цитата:
Сообщение от kriolog Посмотреть сообщение
есть ли способ заменить элемент в списке по номеру
используй subst

Цитата:
Сообщение от kriolog Посмотреть сообщение
Можно обойтись без копирования списка при передаче его в функцию?
По-моему, можно. Попробуй использовать апостроф (')
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 08.03.2012, 12:02
#3
kriolog


 
Регистрация: 14.11.2010
Сообщений: 25


subst заменяет по значению, а мне надо по индексу (заменить 42-й элемент в списке). Использовать безопасные массивы больно не хочется, тк при каждом чихе надо делать кучу преобразований.
kriolog вне форума  
 
Непрочитано 08.03.2012, 12:30
#4
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от kriolog Посмотреть сообщение
Есть большой список и функция, его обрабатывающая и изменяющая.
1. Невозможно изменить список - список НЕИЗМЕНЯЕМАЯ структура, можно только создать новый на основе предыдущего.
2. К списку возможен ТОЛЬКО последовательный доступ (это не массив и nth - по сути отсчитывает car'ы), так что организация порядка в списке "по индексу" - уже по сути своей не есть правильная (посмотрите dxf коды - там нет ни одного значения которое имело-бы фиксированный индекс).
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 08.03.2012, 12:45
#5
kriolog


 
Регистрация: 14.11.2010
Сообщений: 25


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

(defun put (lst i n_i/ ...)
; проверки на границы списка
; добавить в список первые i-1 элементов
; добавить в список i-й элемент
; добавить в список оставшиеся элементы
; реверс результирующего списка
)

или это нарушает какие-то концепции?

Ps. забыл сказать "спасибо" за подсказку про апостроф. Спасибо!

Решил реализовать вычисления на С++. Самый лучший выход, насколько я понял --- сделать com dll. Но времени/желания разбираться в Windows технологиях нет.
Самое простое, что приходит в голову (для внутреннего пользования) --- передача данных через файл:
из лиспа:
1. вывод в input файл
2. вызов .exe с параметром пути к файлу
3. запрос на существование output файла и возможность его записи (то есть на то, что он готов; если не готов --- ждём дальше).
4. чтение output файла

Как можно реализовать п.3?

Последний раз редактировалось kriolog, 08.03.2012 в 14:11.
kriolog вне форума  
 
Непрочитано 08.03.2012, 17:20
#6
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Цитата:
Сообщение от kriolog Посмотреть сообщение
а мне надо по индексу (заменить 42-й элемент в списке)
Код:
[Выделить все]
(defun _Put ( position item lst )
  ((lambda ( i ) 
	 (mapcar
	 '(lambda ( x )
	  (if (eq position (setq i (1+ i)))
	  item
	   x
	   )
	   )
	   lst
	  )
	)
 -1
   ) 
)
Здесь еще 1000+1 вариант Looking for a faster version of delete_nth, insert_nth and switch_nth
Парочка функций из этой темы (там требутся регистрация)
Код:
[Выделить все]
    (defun subst-i (i itm lst)
;;;================================================================================
;;;Ф-ция изменяет i-й(начиная с 0) элемент списка новым значением
;;; i - индекс элемента
;;;itm - новое значение
;;;lst - список
;;;http://www.theswamp.org/index.php?topic=14170.0
      (setq i (1+ i))
      (mapcar
        '(lambda (x)
           (if (zerop (setq i (1- i)))
             itm
             x
           ) ;_ end of if
         ) ;_ end of lambda
        lst
      ) ;_ end of mapcar
    ) ;_ end of defun
    (defun remove-i (i lst)
;;;Ф-ция удаляет i-й(начиная с 0) элемент списка
;;; i - индекс элемента
;;;lst- список

      (setq i (1+ i))
      (vl-remove-if '(lambda (x) (zerop (setq i (1- i)))) lst)
    ) ;_ end of defun
    (defun Insert-i (pos item lst / tmp)
;;;Ф-ция вставляет в позицию pos (начиная с 0) элемент списка item
;;; pos - индекс (позиция) начиная с 0
;;;; item - элемент списка
;;;  lst- список
;_http://www.theswamp.org/index.php?topic=14226.0
       (if (< -1 pos (1+ (length lst)))
        (progn
          (repeat pos
            (setq tmp (cons (car lst) tmp)
                  lst (cdr lst)
            )                                     ;setq
          )                                       ;repeat
          (append (reverse tmp) (list item) lst)
        )                                         ;progn
        lst
      )                                           ;if
    )                                             ;defun
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 08.03.2012, 18:36
#7
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от kriolog Посмотреть сообщение
Решил реализовать вычисления на С++. Самый лучший выход, насколько я понял --- сделать com dll. Но времени/желания разбираться в Windows технологиях нет.
Самое простое, что приходит в голову (для внутреннего пользования) --- передача данных через файл:
1. Что у Вас за вычисления - которые необходимо делать на C++ (такие разумееться могут быть, но все же посмотреть хочется).
2. Если Вы "мудрите" с вычислениями из-за скорости - не займет-ли Ваш "интерфейс" львинную долю времени?
3. Не изобретайте велосипед. То что Вы описали конечно реализуемо, но со стороны похоже на чесание левой пяткой правого уха (с кучей слабых и кривых мест).
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 08.03.2012, 20:22
#8
kriolog


 
Регистрация: 14.11.2010
Сообщений: 25


to VVA: спасибо, пригодится на будущее. Это я так удивлялся, почему subst, nth, sort, etc. встроены, а subst_i --- нет.
to Дима_: код на C++ планирую потом включить в opensource проект (С++/Qt/CGAL) по построению цифровой модели рельефа. Сейчас нужно проверить пригодность алгоритма построения сглаженных горизонталей, основанного на детализации триангуляции. Сами вычисления просты, описаны в книге Скворцова "Триангуляция Делоне и её применение", сс.107-109.
Для тестов тратить время на изучение winapi нецелесообразно. Сначала думал на лиспе быстро накидать, но сейчас вижу, что много времени займёт.
kriolog вне форума  
 
Непрочитано 08.03.2012, 21:49
#9
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Судя по всему, kriolog, вам нужна функция замены списка элементов , а а это несколько иная задача, гонять циклы по одному элементу довольно долго выходит
gomer вне форума  
 
Непрочитано 08.03.2012, 21:56
#10
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


А цифровую модель рельефа в конечном проекте в автокаде выводить будете? Решайте сами - но мне кажеться Вы неправильно к задаче подходите - хотя Вам конечно виднее. Если есть конкретный вопрос по автокаду я (ну или кто другой), скорее всего, на него отвечу, пока я не очень понимаю что нужно.
p.s. не забывайте что лисп язык декларативный, а c++ императивный, подходы в языках разные соответственно и "правильные" алгоритмы для них будут отличаться (в деталях). Например те же списки в c++ как корове седло - одеть можно, но незачем.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Непрочитано 08.03.2012, 22:21
#11
kriolog


 
Регистрация: 14.11.2010
Сообщений: 25


В конечном проекте будет экспорт в dxf. Просто рельеф для теста в dwg, первым порывом было накидать код в autolisp.
kriolog вне форума  
 
Автор темы   Непрочитано 15.03.2012, 03:06
#12
kriolog


 
Регистрация: 14.11.2010
Сообщений: 25


Вот решение для передачи по ссылке:
Код:
[Выделить все]
 
(defun test (%1 %2 / )
  (set %1 42)
  (set %2 (1+ (eval %1)))
)

(setq a -1
      b a)
(test 'a 'b)
(princ a)
;;; 42
(princ b)
;;; 43
Имена такие загадочные, чтобы никто не догадался ... сделать следующее:
Код:
[Выделить все]
 (test '%1 '%2)
ибо результат будет печальный (-1).
kriolog вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > [autolisp] Передача в функцию по ссылке



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача данных в функцию Zaghim Программирование 2 24.08.2011 17:24
VBA AutoCAD передача объекта в функцию ikambi Программирование 13 12.10.2010 16:48
Как правильно вызвать функцию? paradoxvaha Программирование 7 09.07.2008 16:25