簡體   English   中英

如何在C中設置和更改常量變量/結構/指針的值?

[英]How to set and change value of constant variable/ struct/pointer in C?

在.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

將值設置為const結構的唯一方法是在聲明它時對其進行初始化。 因此,解決方案將是:

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

但是,我還沒有遇到過需要這種嵌套const結構的任何情況。

首先:如果看到符合const條件,則應認真對待,避免拋棄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表示“只讀”,而不是“ constant”,所以當用戶嘗試以其他方式更改結構成員時,將結構成員聲明為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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM