【问题标题】:& operator cannot be applied to constants in C [duplicate]& 运算符不能应用于 C 中的常量 [重复]
【发布时间】:2017-08-31 05:16:26
【问题描述】:

根据Kernighan 和 Ritchie 的 C 编程语言,第 94 页

& 运算符不能应用于常量

const int u = 9;
printf ("\nHello World! %u ", &u);

那么,为什么会这样呢?

【问题讨论】:

  • u 通常用于无符号整数......
  • 当书中说常量时,它的意思是 literal 常量。一个变量仍然是一个变量,即使它是 const 限定的。
  • “constant”和“const-qualified variable”不同
  • 作为提示,请对 lvaluesrvalues 进行一些研究。

标签: c pointers constants


【解决方案1】:

您在constantconst 之间存在误解。两者在 C 语言中是不同的东西。

& 运算符不能应用于常量

在C编程中,这意味着你不能在字面常量上使用&(address operator)来获取字面常量的地址。

例如:

&10 

&('a')

如果在字面常量上使用& 运算符,编译器会报错,因为常量实体没有对应的地址。

【讨论】:

  • 'a' 也是一个 int 常量。
【解决方案2】:

根据Draft Standard §6.5.3.2 ¶1,地址运算符的使用必须遵守以下约束:

一元 & 运算符的操作数应为函数指示符、[] 或一元 * 运算符的结果,或一个左值,它指定一个不是位域且未使用 register 存储类说明符声明的对象。

左值的含义在§6.3.2.1 ¶1中给出:

lvalue 是一个可能指定对象的表达式(对象类型不是 void)。

根据§3.15 ¶1,一个对象是:

执行环境中的数据存储区域,其内容可以表示值。

现在,常量 不是左值;常量有值,但常量不代表对象,值不能赋值给常量。 因此,常量不是函数指示符,不是[] 或一元* 运算符的结果,也不是左值,这意味着获取常量的地址是违反约束的。诊断消息必须由符合要求的实现发出。

另一方面,给定const int u = 9;uconst 类型的int 限定变量。此声明确实为变量保留存储空间,u 是一个左值。使用const 并不表示u 是一个常量,而是表示标识符u 表示的对象是const(这不是一回事)。将const 限定变量视为“只读”可能会更好;这是程序做出的承诺,u 指示的对象将不会被修改。由于u 在这里是一个左值(不是位域,并且没有使用register 关键字声明),所以可以使用&u 获取其地址。

请注意,发布的代码具有未定义的行为,因为打印地址的正确 printf() 转换说明符是 %p;它的参数必须转换为(void *)。不匹配的转换说明符和参数会导致未定义的行为。所以,正确的代码是:

const int u = 9;
printf ("\nHello World! %p ", (void *) &u);

【讨论】:

    【解决方案3】:

    不,为了获得变量在内存中的地址,我们可以将指针应用到其中任何一个,因为 CPU 会为所有变量分配内存。另一方面,这个问题已经被问过了。

    C 中的术语“常量”实际上仅表示字面常量,例如 2。 const 限定的对象不是 C 术语中的“常量”

    Link to question

    【讨论】:

      猜你喜欢
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      • 2013-08-12
      • 1970-01-01
      相关资源
      最近更新 更多