2012-02-09 48 views
0

C語言確保指向任何struct的指針可以轉換爲void *,反之亦然。此外,如果語言未定義,語言也允許定義指向struct的指針。我會假設,由於編譯器不知道關於這些結構的任何信息,它們的指針應該具有相同的物理表示。讓我們考慮一下這些線路分成兩個獨立的模塊:指向結構體並投射

/* FILE1.c */ 
void *mem = ...; //Points to a suitable memory block 
struct s1 *p1; //No implementation given for struct s1 
void *mem2; 

p1 = (struct s1 *)mem; 
mem2 = &p1; 


/* FILE2.c */ 
extern void *mem2; 
struct s2 { /*...fields...*/ }; 
struct s2 *p2; 

p2 = *(struct s2 **)mem2; 

這段代碼能夠在所有的平臺上工作,只要該內存塊大到足以容納struct s2(例如,通過malloc(sizeof(struct s2))分配的)?

換句話說,重新解釋包含指向struct s1結構的指針的存儲單元是否正確(即便攜),就好像它是指向struct s2的指針?

(聲明:本人完全清楚,這是指向發揮了非常奇怪的方式,我的問題是理論值)

回答

2

在C語言中,指針不要求具有相同的大小或表示。

這意味着sizeof (int *)可以不同於sizeof (double *)例如。

的唯一要求是:

  • void *char *signed char *unsigned char *有 相同的表示。

  • 指向結構的指針具有相同的表示形式。

  • 指向工會的指針具有相同的表示形式。

+0

當sizeof(int *)與sizeof(double *)不同時,你能舉一個例子嗎? – mikithskegg 2012-02-09 12:09:36

+0

從歷史上看,一些(非常非常古老的)lisp機器具有36位和「標記」地址的字:32位用於普通地址,4位用於數據類型標記。所以一個指針包含有關指針類型的信息,並且一般而言,強制操作不只是位的副本。我不知道今天是否有類似架構的CPU。 – 2012-02-09 13:34:22

+0

@mikithskegg for'int *'和'double *'我不知道但是例如Cray PVP系統對char *有64位表示,對double *有32位表示。 – ouah 2012-02-09 13:39:10

0

是的,你是對的。所有指針都具有相同的大小和結構。它們僅在編譯器的「心智」上有所不同。

+0

這不是真的,指針類型不需要具有相同的表示形式。 – ouah 2012-02-09 11:01:03

0

是的,那是可能的。

指針在其表示中只是一個保存任何數據類型的內存位置地址的整數。

0

這在提取某些數據時很有用。你可以有:

struct s1 
{ 
    char header[4]; 
    int type; 
    char data_max[200]; 
}; 

struct s1_type1 
{ 
    char header[4]; 
    int type; 
    char data_of_some_implementation[80]; 
    char data_of_other_implementation[120]; 
}; 

,然後用它像這樣

struct s1 data; 
int nb = read(fd, &data, sizeof(data)); 
if (nb == sizeof(data)) 
{ 
    if (data.type == 1) 
    { 
    do_something_special((struct s1_type1*)&data); 
    } 
}