4

今天我尝试使用 const 标识符,但我发现 const 变量仍然可以修改,这让我感到困惑..

以下是代码,在 compare(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 如果它们仍然可以更改?

4

4 回答 4

6

它仅在这种情况下有效,因为您正在处理的指针最初不是恒定的。抛弃常量然后修改一个值是未定义的行为。UB的意思是app可以做任何事情,从成功到崩溃到让紫龙飞出你的鼻孔。

于 2012-05-04T21:09:04.937 回答
3

它保护你免受愚蠢的错误,而不是当你努力犯错误时。
(int *)awhen aisconst something *是一种不好的做法,请(const int *)a改用。
a = b什么时候a可以const void *,因为只有指向的值是常量。如果您想要两者都*a = x不允许a = x,请声明aconst void * const.

于 2012-05-04T21:11:46.617 回答
2

案例 1:您正在使用静态强制转换来抛弃 constness。您违反了为该方法定义的合同。

情况 2:您没有更改 a 的内容(即 const),而是分配包含 const void 指针的变量 a。

对于实际影响:对于案例 1.),如果 a 没有真正指向变量,您可能会朝自己的脚开枪。

建议:只有在您知道自己在做什么的情况下,才可以抛弃 constness。

于 2012-05-04T21:13:07.950 回答
1

实际上。

int compare (const void *a, const void*b);

这里有两件事你需要考虑,指针和指针指向的内存位置。指针不是常量,但内存位置是。

如果您将签名更改为:

int compare (const void *const a, const void *const void);

那么一切都会是常量。在您的情况下,您可以更改指针但不能更改值。这样你的指针就可以指向不同的内存位置。

于 2012-05-04T21:13:32.437 回答