【问题标题】:How to implement C code with pointers in Prolog?如何在 Prolog 中使用指针实现 C 代码?
【发布时间】:2013-08-30 12:31:38
【问题描述】:

我是序言的新手。我了解到,虽然它是一种声明性语言,但 prolog 可以用作通用编程语言,就像 C 一样。所以,无论你可以在 C 中解决什么问题,你也可以在 prolog 中解决,即使它运行 -时间可能没有那么好。由于 prolog 中没有指针(据我所知),我想知道是否可以在 prolog 中为以下用 C 编写的代码编写等效程序:-

#include <stdio.h>

int main()
{
    int a = 5;
    int *p;
    p = &a;
    printf("The address of a is %d.", p);
    return 0;
}

【问题讨论】:

  • 不知道序言,但由于显示的代码在c 中,所以想通知说明符%d 不适合指针。您应该使用%p%u
  • 您从哪里得知 Prolog 可以“像 C 一样”使用?
  • 感谢 Dayal rai 提供的信息
  • @Dayalrai %u,期望 unsigned int,与 %d,期望 int 一样不正确。 %p 更好,但在技术上不正确,因为它需要 void*。正确的成语是printf("%p", (void*)p)。详细信息在 C99 标准的第 6.5.2.2 条中(默认参数提升)。
  • Prolog 不支持提取变量的内存地址。因此,我无法编写像您展示的那样的程序。但是,您可以模仿其他程序的某些程序方面,例如 forwhile 循环。

标签: c prolog swi-prolog


【解决方案1】:

使用一个流行的类比,您正在尝试使用螺丝刀钉入钉子。 Prolog 不是 C,在 Prolog 中解决问题与在 C 中解决问题有着根本的不同。

打印一个变量的值很容易做到,例如:

main :-
    X = 5,
    io:format("X = ~w~n", [X]).

但是您不能像在 C 中那样获得 X 的地址。您为什么要这样做?由于 Prolog 具有自动垃圾收集功能,下次地址可能会有所不同。

如果你想学习 Prolog,就不要尝试编写看起来像 C 程序的 Prolog 程序,而是尝试解决实际问题。例如,您可以尝试 Project Euler 系列问题。

【讨论】:

    【解决方案2】:

    除了 cmets 和现有答案之外,还有更多:

    问问自己:你展示的 C 程序有什么用?它解决了什么问题?我无法回答这个问题,我怀疑你也无法回答。孤立地看,这个程序没有任何有用的应用程序!因此,尽管 C 是一种通用编程语言,但您可以编写没有任何目的、通用或特定领域的程序。

    当然,Prolog 也是如此。

    特别是指针:它们是对绝对内存地址的非常薄抽象。您可以通过多种方式使用(和滥用)指针,并且,如果您的算法对于您当前正在解决的问题是正确的,那么编译器可以生成非常高效的机器代码。然而,Prolog 也是如此。然而,范式将非常不同。

    总之,你写了一个如此毫无意义的问题,以至于你激怒了我没有任何代码来回答它。

    附:或者你刚刚成功地欺骗了我们。

    【讨论】:

      【解决方案3】:

      好吧,既然你标记了你的问题,我可以展示我用来与Prolog引擎交换Qt GUI对象(只是指针,你知道......)的代码。

      /** get back an object passed by pointer to Prolog */
      template<typename Obj> Obj* pq_cast(T ptr) {
        return static_cast<Obj*>(static_cast<void*>(ptr));
      }
      

      例如在swipl-win 中使用,其中_read_f 实际上是一个C 回调:

      /** fill the buffer */
      ssize_t Swipl_IO::_read_f(void *handle, char *buf, size_t bufsize) {
          auto e = pq_cast<Swipl_IO>(handle);
          return e->_read_(buf, bufsize);
      

      swipl-win 已成为 SWI-Prolog 中的新控制台。

      【讨论】:

      • 抱歉,当我浏览这个答案时,我在没有注意到的情况下投了反对票,我做了一个虚拟编辑以删除反对票;(
      • @Mog:谢谢,实际上我的回答不是很好,因为用例没有显示使用指针实现的往返行程......
      • 哦,我不是说你的回答不好,这真的是我的误击;)干杯!
      猜你喜欢
      • 1970-01-01
      • 2018-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多