Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 赋值给常数int*_C_Pointers_Constants - Fatal编程技术网

C 赋值给常数int*

C 赋值给常数int*,c,pointers,constants,C,Pointers,Constants,gcc错误:分配只读位置 那么,如何分配给*a,而不使用另一个变量? 那么像上面这样的声明有什么用呢?难道你不能将const赋值给它吗?虽然,我不记得在常量指针的情况下,如果它指向的值不能更改,或者指针的地址。或者两者兼而有之。我猜两者都不能改变 它也可能是您试图写入未初始化内存的一般警告(或错误,具体取决于编译器设置) 正确的答案是(我认为): 问题是你已经创建了一个指针,但它实际上并没有指向任何东西,所以当你取消引用它(或试图写入它引用的loaction)时,你会得到一个错误 void ma

gcc错误:分配只读位置

那么,如何分配给*a,而不使用另一个变量?
那么像上面这样的声明有什么用呢?

难道你不能将
const
赋值给它吗?虽然,我不记得在常量指针的情况下,如果它指向的值不能更改,或者指针的地址。或者两者兼而有之。我猜两者都不能改变

它也可能是您试图写入未初始化内存的一般警告(或错误,具体取决于编译器设置)

正确的答案是(我认为):


问题是你已经创建了一个指针,但它实际上并没有指向任何东西,所以当你取消引用它(或试图写入它引用的loaction)时,你会得到一个错误

void main()
{
   const int* a = new int(5);
}
从右到左阅读声明。[见注释]你得到了什么
a
是一个
*
即指向
int
的指针,即一个整数
const
即一个常数。简而言之,变量
a
指向一个不能更改其值的整数。至少,不是通过
a
。指针对象是否真的是不可变的是另一个问题。但事实仍然是,您不能使用
a
来修改
*a

const
是您对自己的承诺:我永远不会尝试使用指向const的指针修改指针对象。编译器只为您提供支持

如果真的想写入指针对象,则需要一个非常量指针,例如:

const int * a;
还有一个非常好的评论来自:(我想我应该跳过这个来保持简单:)


您还可以将
常量
放在
*
之后(正如您所说,声明应该从右到左读取)

他的意思是:

int *a;
*a = 42; /* this is fine */
这和

const int *a;
(还记得从右向左的阅读规则吗?) 但这与:

int const *a;
阅读它,我们得到:
p
是一个
常量(-ant)
*
(指针)指向
int
(-eger)。一旦你将
p
设置为指向一个整数,你就不能重新放置它(即写入它使它指向另一个整数——使
p
恒定的点),但是你可以非常频繁地写入指针对象(指针对象不是恒定的)

注意:对于学究式倾斜的人,这里的“规则”来自:


“声明应该从右到左读取”是一种简化——如果有括号,它们应该从里到外读取。除非括号表示函数调用。真正的规则是“将其视为表达式;如果我应用这些运算符,最终将得到这个简单类型”

如果不是波茨梅尔和达伦,这个答案的肉会少得多-谢谢

PPS:(我保证这将是最后一次编辑。希望如此!)


<代码>空()/<代码>不是C或C++中的主签名的标准签名。在你了解自己之前不要使用它,或者(更重要的是)你的代码永远不必去另一个宇宙旅行。

你的意思是
int*const
,而不是
const int*
。在一种情况下,指针是const,另一种情况下,指针指向的东西是const。您也可以执行
const int*const
。阅读一些关于const_cast的文章没有什么坏处,它们应该很好地涵盖这一点。

一个例子说明了鲁本·巴特林的出色解释:

int * const p;
#包括
int main()
{
int*常数a=malloc(sizeof(int));
如果(a==NULL)
返回1;
*a=3;
免费(a);
返回0;
}
这里,a是常量(因此必须初始化),但不是*a(可能是OP想要的)。

没有回答“如何分配给*a,而不使用另一个变量?”而只回答“上面这样的声明有什么用?”


这是一种不修改指向的值的承诺。正如在评论中所讨论的,如果您对允许自己使用该结构的方式进行限制,您可能会得出该结构没有用处的结论。但是如果你允许自己使用整个C语言,那么你就可以找到它的用途。想想strcmp的原型吧。

让我用简单的英语回答你的问题

  • 如果我向编译器保证我不会写入变量a指向的值,那么我如何写入变量a指向的值呢
答案是:改变承诺,至少是局部改变

#include <stdlib.h>

int main()
{
  int * const a = malloc(sizeof(int));
  if (a == NULL) 
    return 1;
  *a = 3;
  free(a);
  return 0;
}

希望上面的措辞能清楚地表明这通常是个坏主意。

gcc拒绝承认“新”。所以,我必须使用C++ +?不,只使用MalCube(),而不是No.No,这不是唯一的问题:重读原始消息,这是编译错误。是的,大多数现代编译器能够在编译时检测这些明显的问题,而不是运行时,特别是在一个简单的例子中,比如引用的例子,你不需要运行程序就可以看到会有错误。同样,问题不是OP问题中缺少动态分配。这是一个bug,是的,但即使你修复了它,OP所指出的主要问题仍然存在。你比我先到了那里-耶,胡尔:)。我本打算举一些例子,从{int*I;}到{const int*const I;}以及如何阅读它们,但是生命太短暂了。你也可以把const放在*(正如你所说的,声明应该从右到左阅读。)@Binary-Worrier:不用担心,什么都会发生,什么都会发生:)对我来说,它主要是发生的“const是你对自己做出的承诺”-这是对const用途的一个很好的总结。很好的总结。“声明应该从右到左阅读”是一种简化——如果有括号,它们应该从里到外阅读。除非括号表示函数调用。真正的规则是“将其视为表达式;如果我应用这些运算符,我最终会得到这个简单的类型”。为什么“不使用另一个变量”限制?因为
#include <stdlib.h>

int main()
{
  int * const a = malloc(sizeof(int));
  if (a == NULL) 
    return 1;
  *a = 3;
  free(a);
  return 0;
}
int main()
{
    const int * a;
    *((int *) a) = 5;
}