2012-02-09 45 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); 
    } 
}