什么是常量数组?

3

什么是常量数组?

如果我们定义

const char hex_char[] = {
                           '0', '1', '2', '3', 
                           '4', '5', '6', '7', 
                           '8', '9', 'A', 'B', 
                           'C', 'D', 'E', 'F'
                        };

然后,它不应该被程序修改;这是什么意思?

3
由于const保护其左侧,除非左侧没有内容,因此它也保护其右侧。右侧是数组,在这种情况下,您不能更改数组中的元素。 - Maroun
你说的“protect”是什么意思? - haccks
2
保护它免受恶意更改(不允许所保护的值发生更改),以及因错误或意外而导致的更改。 - Maroun
它如何保护其左侧? - haccks
1
例如,如果您编写 int* const ptr = vec;,那么您不能更改指针 ptr 指向的位置,例如 ptr = NULL* 在左侧)。 - Maroun
1
@haccks 这被称为常量正确性,你应该仔细阅读这个维基教程。 - Grijesh Chauhan
2个回答

13

这意味着您无法修改其内容。例如,不允许执行 hex_char[i] = 'A',否则会导致编译时错误。


7
编译时错误远比运行时错误好得多,这是“const”关键字的优点之一。 - Maroun
如果我想在程序中的某个地方将第10个元素“A”更改为“a”,那么它会显示编译错误,对吗?@Grijesh - haccks
1
@haccks 是的,它会使用我所用的 i,即使您不改变值(任何赋值都是错误的),例如 hex_char[0] = '0'; 就是一个错误。 - Grijesh Chauhan
如果您发现这个答案有帮助(确实如此),请接受它 :) @haccks - Maroun
让我看看其他的答案 :) - haccks
显示剩余3条评论

5
尝试修改常量限定对象会产生未定义的行为。甚至有些C编译器将它们存储在只读内存段中。
正如Grijesh Chauhan指出的那样,直接修改数组应该会产生编译错误。但是使用memcpystrcpy或类似函数可能只会给您警告。然而,这些也不合法。所以不要这样做!

3
因为无法通过去除const来欺骗,所以提到只读段/页的时候要加上+1。这不仅仅是语义修饰符,往往更具实际意义。 - Brett Hale
@BrettHale 但是 ((char*)hex_char)[0] = 'A'; 是有效的,(char) vec 将会出错,因为 vec 是指针,你正在将其转换为 char - Grijesh Chauhan
1
例如:memcpy会将给定数量的字节从源指针复制到目标指针。目标必须是可修改的。如果您意外地将hex_char指定为目标,则memcpy将尝试修改一个const数组。我的观点是,在这种情况下,编译器只会发出警告消息,但它仍然会构建程序。这更加隐蔽,因为这样您最终会在运行时遇到未定义的行为。我想我要说的是,不应忽略编译器警告。 - djf
1
@haccks - 现在,如果vec被声明为const,程序可能会将其内容放入只读数据段中,并由操作系统/CPU本身强制执行。尝试通过(char *)转换修改它通常会导致“分段错误”、“访问冲突”或类似的情况,并终止程序。从技术上讲,C标准将此类事物视为UB未定义行为 - 但这就是实际发生的情况。注意:正如Grijesh指出的那样,在先前的评论中我应该使用(char *)而不是(char) - Brett Hale
@djf; “编译器只会发出警告消息”; 这是否意味着 hex_char 会被修改? - haccks
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接