今天我尝试使用const indentimifier,但我发现const变量仍然可以修改,这让我感到困惑。
以下是代码,在比较(const void *a,const void *b)函数中,我试图修改a指向的值:
#include <stdio.h>
#include <stdlib.h>
int values[] = {40, 10, 100, 90, 20, 25};
int compare (const void *a, const void*b)
{
*(int*)a=2;
/* Then the value that a points to will be changed! */
return ( *(int*)a - *(int*)b);
}
int main ()
{
int n;
qsort(values, 6, sizeof(int), compare);
for (n = 0; n < 6; n++)
printf("%d ", values[n]);
return 0;
}
然后我也尝试更改 a 本身的值:
#include <stdio.h>
#include <stdlib.h>
int values[] = {40, 10, 100, 90, 20, 25};
int compare (const void *a, const void*b)
{
a=b;
return ( *(int*)a - *(int*)b);
}
int main ()
{
int n;
qsort(values, 6, sizeof(int), compare);
for (n = 0; n < 6; n++)
printf("%d ", values[n]);
return 0;
}
但是,我发现它们都有效。谁能向我解释为什么我需要在比较的参数列表中使用 const 如果它们仍然可以更改?
它仅适用于这种情况,因为您正在使用的指针最初不是常量。抛弃恒常性,然后修改值是未定义的行为。UB意味着该应用程序可以做任何事情,从成功到崩溃,让紫色龙从你的鼻孔里飞出来。
它可以保护你免受愚蠢的错误,而不是当你努力犯错误时。
(int *)a
当a
const something *
是一种不好的做法时,请改用(const int *)a
。
a = b
当a
const void *
是可以的,因为只有指向的值是常量。 如果您希望同时禁止*a = x
和a = x
,请将a
声明为 const void * const
。
情况 1:您正在使用静态强制转换来抛弃恒常性。您违反了为该方法定义的协定。
情况 2:您不是在更改 a(这是 const)的内容,而是分配包含 const void 指针的变量 a。
对于实际含义:案例 1.)你可以搬起石头砸自己的脚,以防 A 没有真正指向一个变量。
建议:只有当你知道自己在做什么时,才能抛弃恒心。
实际上。
int compare (const void *a, const void*b);
这里有两件事需要考虑,指针和指针指向的内存位置。指针不是常量,但内存位置是常量。
如果要将签名更改为:
int compare (const void *const a, const void *const void);
然后一切都会变得恒定。在您的情况下,您可以更改指针,但不能更改值。以便指针可以指向不同的内存位置。