【问题标题】:How to set and change value of constant variable/ struct/pointer in C?如何在 C 中设置和更改常量变量/结构/指针的值?
【发布时间】:2019-04-04 06:10:08
【问题描述】:

在.h文件中

typedef enum
{A1,A2}struct_A;

typedef struct
{const struct_A G;} struct_B;

typedef struct
{const struct_B * F;} struct_C;

typedef struct
{const struct_C *E;} struct_D;

在 .c 文件中

const struct_D temp;

如何设置/更改:

temp->E[i].F[0].G

【问题讨论】:

  • 请确保您发现自动大写并修复它 - 手机是在 SO 上输入代码的威胁。 TypedefConst 的使用最终是粗心的,程序员不能粗心。
  • temp在定义的时候需要初始化(这是一个比较复杂的操作);此后,您不应该尝试修改存储(通过名称temp)。如果要修改存储,不要使用const。如果您尝试修改存储,编译器会抱怨(我假设您不会询问它是否没有抱怨),并且您调用 undefined behavior 这总是 A Bad Thing!™
  • struct_B b = {A1}; struct_C c = {&b}; const struct_D temp = {&c};
  • @Tiến Nguyễn 不确定这是否是题外话,但你为什么需要这样的嵌套结构。由于 struct_B 和 struct_C 具有指针,因此 B.G 中的任何更改都会自动更改 temp.E->F->G 中的值。除非这是一个好奇心/学习阶段/家庭作业问题,否则我认为没有理由在这里使用 const 关键字。

标签: c pointers struct constants


【解决方案1】:

将值设置为const 结构的唯一方法是在声明它时对其进行初始化。所以,解决办法是:

struct_B B = {A1}; 
struct_C C = {&B};  
struct_D temp = {&C};

但是,我还没有遇到需要这种嵌套 const 结构的情况。

【讨论】:

    【解决方案2】:

    首先:如果我们看到有const 的东西,我们应该认真对待它,避免抛弃常量。如果你抛弃全局或静态数据的 const 限定符,那么你会得到未定义的行为,并且你会在 linux 中遇到分段错误。

    一般来说,正确的方法是 Suven Pandey 在另一个答案中指出的那个。

    但是,有一些有效的情况可以抛弃 const。您的案例可能符合https://wiki.sei.cmu.edu/confluence/display/c/EXP05-C.+Do+not+cast+away+a+const+qualification中的例外情况之一@

    EXP05-C-EX3:因为 const 表示“只读”而不是“常量”,所以有时将结构成员声明为(指向)const 对象以在用户尝试更改它们时获得诊断信息很有用除了通过专门设计用于维护该数据类型的函数之外的某种方式。然而,在这些函数中,可能需要去掉 const 限定来更新这些成员。

    当您的数据位于内存的可变区域(如堆栈或堆)中时,我们可以丢弃 const。无论如何,我们需要小心,因为如果代码依赖于不可变的数据并且我们更改它,这可能会产生意外行为。

    所以,这就是你要求的:

    typedef enum {A1, A2} enum_A;
    typedef struct { const enum_A G; } struct_B;
    typedef struct { const struct_B * F; } struct_C;
    typedef struct { const struct_C *E; } struct_D;
    
    int main() {
       const struct_B b = {A1};
       const struct_C c = {&b}; 
       const struct_D temp = {&c};
       enum_A *pointer_to_non_const_A = &temp.E[0].F[0].G;
       *pointer_to_non_const_A = A2;
    }
    

    但这取决于temp 的定义位置以及会导致编译警告的位置。如果temp 是一个将会崩溃的全局变量。以下是它可以工作但不应使用以及崩溃的情况:

    #include <stdlib.h>
    
    const int global_in_data_segment = 0;
    
    int main() {
        const int in_stack = 0;
        static const int static_in_data_segment = 0;
        const int *in_heap = malloc(sizeof(int));
    
        int *works;
        works = &in_stack; *works = 1;
        works = in_heap; *works = 2;
    
        int *crashes;
        crashes = &global_in_data_segment; *crashes = 3;
        crashes = &static_in_data_segment; *crashes = 4;
    }
    

    为了完整起见,c++ 有 const_cast: https://en.cppreference.com/w/cpp/language/const_cast

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多