3

我是 C 的新手,我目前正在用 C 实现一个 Scheme 解释器。我接近尾声了,但一个问题困扰着我,我还没有解决。

我想要一个指向结构的“globalEnvironment”指针,该指针在程序运行期间保持不变并且也被修改(不是常量)。

/****************************************************************
 Creates the List as a pointer to the conscell structure
 */
typedef struct conscell *List;

/****************************************************************
 Creates a conscell structure, with a char pointer (symbol) and two pointers to
 * conscells (first and rest)
 */
struct conscell {
    char *symbol;
    struct conscell *first;
    struct conscell *rest;

};


List globalEnvironment;


/****************************************************************
 Function: globalVariables()
 --------------------
 This function initializes the global variables
 */
void globalVariables() {

globalEnvironment = malloc(sizeof (struct conscell));
globalEnvironment->symbol = NULL;
globalEnvironment->first = NULL;
globalEnvironment->rest = NULL;

}

如您所见,“List”是一个指向 conscell 结构的指针。所以我想要的只是 globalEnvironment List 是全球性的。

问题是我不能在那里做 malloc 。如果我尝试以下操作:

List globalEnvironment = malloc(sizeof (struct conscell));

而不仅仅是“列出 globalEnvironment;” 它给出了一个错误,“初始化元素不是常量”

为了解决这种情况,我创建了一个新函数“globalVariables”,它在程序开始时运行,初始化 globalEnvironment 并为其分配内存。但它并没有像我预期的那样工作,并且我不断收到其他功能的分段错误错误,我没有在这里编写以保持简单。

是否有另一种更简单的方法来声明指向 C 中结构的指针(不是常量)?

希望有人能帮忙,谢谢

4

3 回答 3

6

malloc当您应该只使用全局数据时,您似乎正在尝试这样做。你可以试试

struct conscell globalEnvironment;

只要记住永远不要free它。

如果您需要一个指针句柄,以便您可以推送列表中的单元格:

struct conscell _globalEnvironment;
List globalEnvironment = &_globalEnvironment;

不过,请记住永远不要free _globalEnvironment

于 2012-12-11T07:26:40.370 回答
1

malloc()是一个函数并调用任何函数(在运行时完成),因此它必须位于main()或其他函数定义中。

全局变量也必须有初始化列表必须是一个常量表达式。

ISO :c99 , 6.5.2.5 Compound literals : paragraph 3rd of constraints,

3
If the compound literal occurs outside the body of a function, the initializer list shall consist of constant expressions.

malloc()因此,当您在List任何函数体之外调用指针时,您会收到该错误。

于 2012-12-11T07:05:38.580 回答
1

我认为这是某种链表或类似的动态 ADT,这就是您要使用 malloc 的原因。

这就是您如何通过正确的面向对象的程序设计来实现此功能:

conscell.h

/****************************************************************
 Creates a conscell structure, with a char pointer (symbol) and two pointers to
 * conscells (first and rest)
 */
typedef struct conscell {
    char *symbol;
    struct conscell *first;
    struct conscell *rest;
} conscell_t;


void conscell_init (void);
void conscell_cleanup (void);
void conscell_add (something); // function that accesses the object

conscell.c

#include "conscell.h"
#include <stdlib.h>

static conscell_t* environment;


void conscell_init() 
{
  environment = malloc(sizeof (conscell_t));

  if(environment == NULL)
  {
    // error handling
  }

  environment->symbol = NULL;
  environment->first  = NULL;
  environment->rest   = NULL;
}

void conscell_cleanup (void)
{
  // perform all custom freeing of dynamic memory here

  free(environment);
  environment = NULL;
}

void conscell_add (something)
{
  // do something with "environment" here.
} 
于 2012-12-11T09:54:53.287 回答