C 如何初始化全局常量指针?

C 如何初始化全局常量指针?,c,constants,global-variables,C,Constants,Global Variables,我有一个变量,它是链表的头。我想把它设为常量,因为它永远不应该被改变,变量在整个程序中都被使用,所以我想我应该把它设为全局常量。问题是我在声明它为const之后无法初始化它 我怎样才能避开这个问题 typedef struct PT { int x; int y; struct PT *next; } POINT; //globals POINT * const mypoint_head; int main(int argc, char *argv[]) { int size

我有一个变量,它是链表的头。我想把它设为常量,因为它永远不应该被改变,变量在整个程序中都被使用,所以我想我应该把它设为全局常量。问题是我在声明它为const之后无法初始化它

我怎样才能避开这个问题

typedef struct PT {
 int x;
 int y;
 struct PT *next;
} POINT;

//globals
POINT * const mypoint_head;

int main(int argc, char *argv[])
{
    int size = 100;
    mypoint_head= InitPoint(size);   // error C2166: l-value specifies const object
    //rest of code

}


POINT* InitPoint(int size)
{
   POINT *tmp;
   POINT *orig;
   int a = 10;
   int b = 1000;
   orig = (POINT*) malloc (sizeof(POINT) * size);
   if(orig == NULL)
      return NULL;

   tmp = orig;
   for (i = 0; i < size; i++)
   {
      tmp->x = a++;
      tmp->y = b++;
      if (i == size -1) {
            tmp->next = NULL:
      }
      else {
            tmp->next = tmp+1; 
      }
      tmp++;
   }
   return orig;
} 
typedef结构PT{
int x;
int-y;
结构PT*next;
}点;
//全球的
点*const mypoint\u head;
int main(int argc,char*argv[])
{
int size=100;
mypoint_head=InitPoint(size);//错误C2166:l值指定常量对象
//代码的其余部分
}
点*InitPoint(整数大小)
{
点*tmp;
点*原点;
INTA=10;
int b=1000;
orig=(点*)malloc(尺寸(点)*尺寸);
if(orig==NULL)
返回NULL;
tmp=orig;
对于(i=0;ix=a++;
tmp->y=b++;
如果(i==大小-1){
tmp->next=NULL:
}
否则{
tmp->next=tmp+1;
}
tmp++;
}
返回原点;
} 

你不能-这就是
const
的全部要点,你必须在声明中使用初始值设定项:

static POINT mypoint_data[100];
POINT * const mypoint_head = &mypoint_head;
然后更改InitPoint函数以获取指向数据空间的指针,而不是调用
malloc
,并将其传递给
mypoint\u data


您还可以粘贴
extern POINT*const mypoint\u head,以便在其他编译单元中访问它。

从全局声明中删除常量限定符,并将代码的剩余部分声明为一个函数,该函数接受指针的常量限定版本

//globals
POINT * mypoint_head;

void rest_of_code(POINT* const mypoint_head)
{
    mypoint_head = NULL;    // this errors out now
}
int main(int argc, char *argv[])
{
    int size = 100;
    mypoint_head= InitPoint(size);   // no longer errors out
    //rest of code
    rest_of_code(mypoint_head);
}
(假设c)const在声明时必须初始化,并且无法对其求值。也许您可以使用一个常量指针,让它指向您的头部,并将其公开给代码的其余部分。 如果必须实现may,我将通过getListHead()函数公开该变量,并给它取一个不太清楚的名称:)


想知道用例是什么。我会让我的列表工作,即使它的头指针改变。(如果我有一个常量head,如果我必须删除head节点,我将不得不像在数组中一样移动元素)

您是正确的,因为声明的变量
const
永远不能更改。不幸的是,您的
mypoint\u head=InitPoint(size)行计数为尝试更改变量。声明
const
变量时,必须使用值初始化该变量

请尝试以下方法:

//globals
static POINT head_of_list;
POINT* const mypoint_head = &head_of_list;
现在,您可以使用以下命令初始化列表:

mypoint_head->next= InitPoint(size-1);

列表头对象是静态声明的,因此它始终存在,您需要适当地调整
InitPoint
参数。您还可以在另一个文件中对指针进行
extern
引用,而无需直接访问指针所指向的对象(不管它值多少钱)。

目前还没有人建议这样做:

int main(int argc, char *argv[])
{
    int size = 100;

    // cast address of mypoint_head to a non-const pointer:
    POINT ** nc_pmh = (POINT **)&mypoint_head;
    // use the address to set mypoint_head:
    (*nc_pmh) = InitPoint(size);
    //rest of code
}
<>这可能在C++中不起作用,因为它可能不为const对象提供空间。 顺便说一句:这通常不是好的做法。然而,在这种情况下,效果很好


顺便说一句:您需要检查来自
InitPoint()
的返回,并相应地采取行动(可能调用exit()。

没有全局常量指针作为指向其他所有内容的接口

使用函数:-

static POINT * mypoint_head;

POINT* point_head()
{
    return mypoint_head;
}

我不敢相信还没有人建议康斯特卡斯特。。对于常量指针,它也同样有效

const_cast<POINTER *>(mypoint_head) = InitPoint(size);
const_cast(mypoint_head)=InitPoint(size);

就这么简单,没有额外的变量声明,什么都没有。

当您可以更改列表的任何其他部分时,const head ptr的优势是什么?这就像给茅草屋加上一扇铁门。@Amardeph:我认为这更像是用墨水而不是铅笔写某人的地址。不同的人可能进进出出,但房子总是在同一个地方(除非你住在肯塔基州)。@Amardeep@Tim Schaeffer-是的,Tim,我的意图是防止改变我的“头”指针,以后无法释放内存,从而泄漏它。。。有更好的方法吗?还是像…那么简单。。。如果是“头”,不要改变它。我给它起了一个不同的名字,并在另一个函数中意外地更改了它,直到我意识到我不想这么做。这允许您初始化指针,而无需去掉常量。任何其他改变它的代码都必须经过相同的难看的转换,这是你不可能偶然做到的。通常,为了避免“泄漏”列表,我要么静态声明第一个列表项(而不仅仅是指向第一个项的指针),要么声明两个指向列表顶部的指针(一个供应用程序使用,另一个只是一个指针)“备份”指针,只能由负责分配和删除列表的代码访问)。为什么我希望函数具有全局参数?这不是违背了全局的目的吗?另一方面,我不能将其设为全局并使用您的策略…处理“头”的最佳方法是什么“链接到链表,以便它们不会被意外修改,并且内存丢失?呃,也许您不应该将头标记为const,而应该提供用于列表操作的函数,并且只能通过这些函数访问列表。@emge-如果您担心将头丢失到列表并泄漏内存,然后静态声明head节点,动态声明列表的其余部分。这样,头部节点就不会“丢失”。谢谢bta。。。我非常喜欢您的解决方案,但我选择了另一个实现,原因有两个:A)我不想混合静态和动态元素B)我不想将参数更改为initpoint
static
部分完全是可选的;这两种方法都可以。。。。或者如果您可以接受宏:POINT*POINT\u head\u get(){return mypoint\u head;}#define POINT\u head\u get(),这就是在mingw中定义stdout的方式。这是未定义的行为,您的编译器可能会在最坏的情况下让您大吃一惊