C中的常量:声明与定义分开

C中的常量:声明与定义分开,c,gcc,constants,C,Gcc,Constants,所有C代码: 为什么允许这样做: int main() { const int *i; int j=2; i=&j; } 但不是这个: int main() { const int i; int j=2; i=j; } 有没有办法声明一个局部常量变量,然后在范围内的其他地方定义它?第一种使用指针的情况是不可靠的,因为我可以多次定义它,这首先破坏了常量关键字的用途。const int*I意味着I指向的int是const,因此您不能执行

所有C代码:

为什么允许这样做:

int main()
{
    const int *i;
    int j=2;

    i=&j;
}
但不是这个:

int main()
{
    const int i;
    int j=2;

    i=j;
}

有没有办法声明一个局部常量变量,然后在范围内的其他地方定义它?第一种使用指针的情况是不可靠的,因为我可以多次定义它,这首先破坏了常量关键字的用途。

const int*I
意味着
I
指向的
int
const
,因此您不能执行
*I=j
。但是
const int i
意味着
i
本身就是
const
,所以您必须像
const int i=2那样声明它然后它保持常量,不能被触摸

区别在于你改变了什么。如果您有一个
const
整数-它不能更改,如果您有一个指向
const
整数的指针-并且指针不是
const
,那么可以将该指针指定给您想要指向的任何
int


回答您的问题:不,您不能定义一个
const int
,然后重新定义它。这否定了const的含义,第一个例子在语义上是指“指向常量int的指针”,而不是“指向int的常量指针”

所以,当你将i设置为指向j(一个非常量int)时。我现在指向一个常量,因此不能通过指针i更改j的值,例如:

int main()
{
    const int *i;
    int j=2;

    i=&j;

    *i = 4;
}
将不编译,给出错误“分配只读位置'*i'”。因此,指针限制您对所指向的值的访问。但指针本身仍然可以更改

C作为一种语言,并不能提供太多的保护,您通常可以丢弃常量并为变量指定一个新值,例如:

#include <stdio.h>

void assign(int *a) {
  *a=5;
}

int main()
{
    int const i=1;
    int j=2;
    assign((int *) &i);
    printf("i: %d\n",i);
}
#包括
无效分配(int*a){
*a=5;
}
int main()
{
int const i=1;
int j=2;
分配((int*)&i);
printf(“i:%d\n”,i);
}

但我不确定我会推荐它。虽然这在某些版本的gcc中有效,但这种行为在C标准中可能没有定义

别开玩笑了。但我的问题是,我是否可以“声明”然后定义,而不是定义然后定义。正如在“先分配类型,然后再分配值”中一样。将“you”拼写为“u”会使您的答案更难阅读。那么@Sanfer范围内所有变量的声明也都是定义,在范围内没有“变量的前向声明”之类的东西。(全局变量有这样一个概念)谢谢,你的第一句话解释了这一切。但是有没有一种方法可以声明一个常量变量,然后在以后定义它呢?没有办法做到这一点似乎很愚蠢。@Sanfer好吧,我不相信你能做到你想要的。但是C中的常量通常不提供太多的保护,您通常可以将常量变量改写为非常量并对其进行修改。我已经用一个例子更新了上面的内容。很好,这是我需要的答案,谢谢。不管怎样,我还是要这样做,因为1)样式,因为它很好,首先声明所有变量,然后在后面定义/操作2)需要使用函数进行常量赋值,防止意外I=4;诸如此类的事情,这正是我最初的意图。你的第二个例子导致了未定义的行为,我不确定它应该说明什么。你似乎愚弄了OP,以为这是可以接受的code@Sanfer在需要变量之前不声明变量是一种很好的风格。也许你被早期的C代码误导了,在代码块的开头声明了变量;这是因为历史编译器无法处理在任何地方声明的变量——这不是一个风格决定