所以我在假期里一直在努力学习C语言.现在我遇到了const个,所以我一直在玩弄它.过了一会儿,我发现了这一点

#include <stdio.h>

typedef struct StructA {
    int* ptr;
} struct_a;

void modify(const struct_a value)
{
    *value.ptr = 0;
}

int main()
{
    int x = 5;
    const struct_a y = { .ptr = &x };
    printf("%d\n", x);
    modify(y);
    printf("%d", x);
    return 0;
}

// Output:
// 5
// 0

我的一般 idea 是,虽然 struct 是常量,但指针所指向的值不是常量,因此可以修改它.有人能解释一下这里到底是怎么回事吗?

编辑:稍加修改

推荐答案

该函数通过值接受其参数

void modify(const struct_a value)
{
    *value.ptr = 0;
}

您可以通过以下方式想象该函数及其调用

const struct_a y = { .ptr = &x };
//...
modify(y);
//...

void modify( /*const struct_a value*/)
{
    const struct_a value = y;
    *value.ptr = 0;
}

这意味着对象值的数据成员PTR是恒定的.

也就是说,函数中的 struct 实际上具有以下定义

typedef struct StructA {
    int * const ptr;
} struct_a;

因此,您不能更改数据成员PTR本身(存储在数据成员PTR中的值).但您可以更改数据成员PTR所指向的对象

*value.ptr = 0;

由于函数参数和实参中的指针ptr指向同一对象,因此可以更改main中声明的 struct 的指针所指向的对象

考虑一下这些声明

const int *ptr = &x;

这意味着指针PTR所指向的对象被视为常量.

在这份声明中

int * const ptr = &x;

指针本身就是一个常量.

最后,在这份宣言中

const int * const ptr = &x;

指针本身和指针指向的对象都是常量.

C++相关问答推荐

为什么这个C程序代码会产生以下结果?

是否有任何情况(特定类型/值),类型双关在所有符合标准的C实现中产生相同的行为?

为什么GCC在每次循环迭代时都会生成一个数组的mov&S使用[]访问数组?(-03,x86)

将宏值传递给ARM链接器,该链接器将变量放置在特定位置

GCC创建应用于移动项的单独位掩码的目的是什么?

用gcc-msse 2编译的C程序包含AVX 1指令

从C文件中删除注释

为什么Fread()函数会读取内容,然后光标会跳到随机位置?

GCC奇怪的行为,有fork 和印花,有换行符和不换行符

在C++中允许使用字符作为宏参数

将数组插入数组

如何在c中使用具有不同变量类型的内存分配?

我不知道为什么它不能正常工作,我用了get()和fget(),结果是一样的

共享目标代码似乎不能在Linux上的进程之间共享

';malloc():损坏的顶部大小';分配超过20万整数后

从文件到链表读取日期

无法理解 fgets 输出

为什么程序在打印每个数字之前要等待所有输入?

定义 int a = 0, b = a++, c = a++;在 C 中定义了行为吗?

Rust 的 (void) 变量替代品