C 如何初始化全局常量指针?
我有一个变量,它是链表的头。我想把它设为常量,因为它永远不应该被改变,变量在整个程序中都被使用,所以我想我应该把它设为全局常量。问题是我在声明它为const之后无法初始化它 我怎样才能避开这个问题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
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)我不想将参数更改为initpointstatic
部分完全是可选的;这两种方法都可以。。。。或者如果您可以接受宏:POINT*POINT\u head\u get(){return mypoint\u head;}#define POINT\u head\u get(),这就是在mingw中定义stdout的方式。这是未定义的行为,您的编译器可能会在最坏的情况下让您大吃一惊