2012-03-27 78 views
1
#include <stdio.h> 

typedef struct { 
    int a; 
    int b; 
    int c; 
} FIRST_T; 

typedef struct { 
    int x; 
    int y; 
    int z; 
    FIRST_T *p; 
} SECOND_T; 

typedef struct { 
    int a1; 
    int a2; 
    int a3; 
    FIRST_T *q; 
}THIRD_T; 

const FIRST_T p1[]={{1,2,3},{3,4,5},{6,7,8}}; 
const FIRST_T p2[]={{4,5,12},{7,8,9}}; 
const SECOND_T my_second[]= 
{ 
    {1,2,3,p1}, 
    {4,5,6,p2} 
}; 
const THIRD_T my_third[] = {{1,2,3,my_second[1].p},{4,5,6,my_second[0].p}}; 

int main() { 
    //const THIRD_T my_third[] = {{1,2,3,my_second[1].p},{4,5,6,my_second[0].p}}; 
    printf("%d %d %d %d \n", 
     my_third[0].a1, 
     my_third[0].a2, 
     my_third[0].a3, 
     my_third[0].q[1].c); 
} 

我知道,如果我在函數範圍內初始化my_third它工作正常,如「在C,具有靜態存儲持續時間對象,如在文件範圍內聲明的對象只能用常量表達式初始化「否則它給了我:錯誤:初始元素不是常數

錯誤:初始元素不是常數 new.c:41:錯誤:(近初始化`my_third [0] .Q」)

現在我的問題是:是否有任何解決方法我沒有移動功能內的表達式。我無法移動,因爲這些結構在我的代碼中的很多地方都使用過。

如果您需要更多信息,請讓我知道。

+0

你真的需要修復縮進和張貼代碼本網站前添加類型定義之間有一些空行。 – Lundin 2012-03-27 06:45:06

回答

0

怎麼樣

const THIRD_T my_third[] = {{1,2,3,p2},{4,5,6,p1}}; 

,因爲它正是你會得到價值?

爲了使變化更容易,你可以換這樣的層

const FIRST_T p1[]={{1,2,3},{3,4,5},{6,7,8}}; 
const FIRST_T p2[]={{4,5,12},{7,8,9}}; 

#define first_p p1 
#define second_p p2 

const SECOND_T my_second[]= 
{ 
{1,2,3,first_p}, 
{4,5,6,second_p} 
}; 
const THIRD_T my_third[] = {{1,2,3,second_p},{4,5,6,first_p}}; 

,然後只需更改#define S IN爲了保持my_secondmy_third同步。

另一種選擇可能是將THIRD_T更改爲包含SECOND_T而不是FIRST_T。然後(也許)有#define做簡化訪問:

typedef struct { 
int a1; 
int a2; 
int a3; 
SECOND_T *qq; 
}THIRD_T; 

#define q qq->p 

使

my_third->q 

有效

my_third->qq->p 

變。

0
typedef struct { 
    int x; 
    int y; 
    int z; 
    FIRST_T *p; 
} SECOND_T; 

當你聲明這個結構const的一個變量,它的所有成員成爲const,在他們得到存儲在ROM中。 int const x;int const y;等。對於指針,這意味着它變成FIRST_T * const p;。也就是說,一個指向非常數數據的const指針。但是指向的類型仍然不是const!我懷疑這就是爲什麼你會遇到問題。

{1,2,3,p1}, 

p1屬於數組類型並衰變爲const FIRST_T p1* const(常量指針指向常量數據)。您嘗試將其分配給FIRST_T * const p;(常量指針指向非常量數據)。要解決此問題,請嘗試聲明類型爲

typedef struct { 
    int x; 
    int y; 
    int z; 
    const FIRST_T *p; 
} SECOND_T; 

typedef struct { 
    int a1; 
    int a2; 
    int a3; 
    const FIRST_T *q; 
} THIRD_T; 

使用MinGW,GCC 4.6.2進行測試。

  • -std = c99 -pedantic編譯正常。
  • -std = c89 -pedantic給出警告。 「警告:初始化器元素在加載時不可計算[缺省情況下啓用]」。

(我不知道該標準,這種情況下的區別,所以我寧願不猜測爲什麼它在C99和C89沒有。可能與VLA?)

1

醜陋方法:

#include <stdio.h> 

struct first_t { 
    int a; 
    int b; 
    int c; 
}; 

struct second_t { 
    int x; 
    int y; 
    int z; 
    const struct first_t *p; 
}; 

struct third_t { 
    int a1; 
    int a2; 
    int a3; 
    const struct first_t *q; 
}; 

const struct first_t p1[] = { 
    {1, 2, 3}, 
    {3, 4, 5}, 
    {6, 7, 8} 
}; 
const struct first_t p2[] = { 
    {4, 5, 12}, 
    {7, 8, 9} 
}; 
const struct second_t my_second[] = { 
    {1, 2, 3, p1}, 
    {4, 5, 6, p2} 
}; 
const struct third_t my_third[] = { 
    {1, 2, 3, (const struct first_t*)&my_second[1].p}, 
    {4, 5, 6, (const struct first_t*)&my_second[0].p} 
}; 

int main(void) { 
    fprintf(stdout, 
     "PRNT: %d %d %d %d\n", 
     my_third[0].a1, 
     my_third[0].a2, 
     my_third[0].a3, 
     my_third[0].q[1].c 
    ); 

    return 0; 
} 

給出:

/* gcc -Wall -Wextra -pedantic -std=c89 -ggdb -o bad fmts.c && ./bad 
* 
* PRNT: 1 2 3 4 
* 
* */ 
相關問題