【问题标题】:Does "nonmodifiable" in C mean the same as "immutable" in other programming languages?C 中的“不可修改”是否与其他编程语言中的“不可变”相同?
【发布时间】:2018-02-21 14:42:52
【问题描述】:

简而言之,从 C 语言来看,数组和字符串文字是不可修改的左值。

C 中的“不可修改”与编程语言(例如 Python、Java 和函数式语言)中的“不可变”的含义相同吗?

在编程语言设计中,数组的“不可修改”和“不可变”对其元素/项是否意味着相同?

为什么我们可以在 C 中修改数组元素的值和字符串字面量,而在 Python 中却不能修改字符串中的项?

谢谢。

【问题讨论】:

  • Why can we modify the value of an element of an array and string literals in C 您不能在 C 中修改字符串文字。它是文字。不过你可以修改数组。
  • "为什么我们可以在 C 中修改数组元素的值和字符串字面量,而在 Python 中却不能修改字符串中的项?"为什么 C 和 Python 应该是一样的?如果所有语言都相同,那么存在不同的语言就没有意义了。
  • 如何在 C 中修改字符串文字?
  • @Sraw 语言会让你说char *s = "abcde"; s[1] = 'x';。这取决于机器架构。我们习惯使用的机器支持虚拟内存并允许您将块标记为只读,在这种情况下编译器应该将字符串文字放在只读区域中,s[1] = 'x' 可能会导致程序崩溃。但我使用过的嵌入式系统不具备这种能力。所以你最终会在内存中得到"axcde"

标签: java python c programming-languages immutability


【解决方案1】:

根据您对问题的措辞——指的是“不可修改的左值”——我认为答案是:不,不可修改与不可变不一样,至少在您正在阅读的书的上下文中. “不可变”是面向对象语言中对象的属性。 (在 C 语言中,我认为 const 对象也被认为是不可变的。)“左值”更多地与编译器如何对表达式进行分类有关。我理解它的方式,“左值”是一个引用对象的表达式,而“右值”不是。您不能将右值放在赋值的左侧。大多数左值可以分配给,但有些不能。根据语言规则,字符串文字被视为左值,但您不能说"abc" = "xyz";。这就是为什么它被认为是不可修改的左值。

http://ieng9.ucsd.edu/~cs30x/Non-modifiable%20Lvalues.htm 很好地解释了这一点。除其他外,作者说

请注意,我没有说不可修改的左值指的是对象 你不能修改-我说你不能使用左值来修改 对象。

C 实际上会让你修改任何东西,如果你知道怎么做的话。如果 C 中的某些内容无法修改,那是因为硬件和/或操作系统不允许您修改。如果您在嵌入式系统上运行,该系统没有内置方法来防止写入一定范围的内存,那么您可以修改任何内容,包括您自己的代码。这里的重点是,C 语言中的任何内容都不允许尝试修改字符串文字是非法的。

相比之下,在 Java 和 Python 中,字符串是对象,因此您可以对它们执行的唯一操作是为字符串类定义的操作。而且这些类根本不提供允许您修改字符串的方法。这就是不可变的意思。这是一个适用于对象的术语,而您对“不可修改”的使用实际上仅适用于某些语法类别的表达式。所以你根本不能把两者等同起来。

【讨论】:

  • 感谢您的链接。我想说一个内存位置可以解释为具有不同可变性的不同类型的对象intconst int
【解决方案2】:

C 中的“不可修改”与编程中的“不可变”的意思一样吗 语言(例如 Python、Java 和函数式语言)?

是的。

在编程语言设计中,“不可修改”和“不可变” 数组的元素/项目是否意味着相同?

没有。数组是不可变的,因为您不能修改它存储的地址,该地址指向序列的第一个元素。但是,您可以修改数组的元素。

为什么我们可以修改数组和字符串的一个元素的值 C中的文字

停在那里。您不能在 C 中修改字符串文字。您可以修改字符串的地址,但不能修改字符串本身。

这里有一个小程序来演示数组和字符串字面量之间的区别:

int main(){
  char* a = "somestring";
  char* b = "oldstring";
  char c[] = "somestring2";
  b = a;//OK, you modified the address. Now it stores the address of the first char from string a
  *b = 'l';//not OK, you modified the string(its first character)
  c = a;//not ok, you're changing the address the array holds
  *c = 'j';//OK, modifying array's elements(first char)
}

【讨论】:

  • 可能能够修改 C 中的字符串文字,具体取决于您运行的机器类型。请看我上面的评论。 *b = 'l' 在您的示例中是合法的,但在大多数机器上,当您尝试运行它时它会出错。
  • “数组保存的地址”是无意义的,数组没有保存地址。
猜你喜欢
  • 2011-02-26
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-11
  • 2014-03-28
相关资源
最近更新 更多