为什么我可以修改C中的const指针?

时间:2012-05-04 21:07:28

标签: c memory pointers

今天我尝试使用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 个答案:

答案 0 :(得分:6)

它只适用于这种情况,因为您正在使用的指针最初不是常量。抛弃const然后修改值是未定义的行为。 UB意味着应用程序可以做任何事情,从成功到崩溃,让紫色的龙飞出你的鼻孔。

答案 1 :(得分:3)

它保护你免受愚蠢的错误,而不是当你努力犯错时 (int *)aaconst something *是不好的做法,请改用(const int *)a
a = ba时,const void *是正常的,因为只有指向的值是const。如果您同时禁止*a = xa = x,请将a声明为const void * const

答案 2 :(得分:2)

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

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

对于实际意义:对于案例1.)你可以用脚射击自己,以防没有真正指向变量。

建议:只有在你知道自己在做什么的情况下才能抛弃常量。

答案 3 :(得分:1)

实际上。

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

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

如果您要将签名更改为:

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

然后一切都将是const。在您的情况下,您可以更改指针,但不能更改值。这样你的指针就可以指向不同的内存位置。