大家好。我正在使用名为 C 中的指针:实践方法
的书来研究结构和指针,在第 107 页,我遇到了一个不完整的结构类型转换示例。我试图通过仅实现函数 receivedata()
、添加 header 并进行一些更改来使其工作。
这是完整的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct signature
{
char sign;
char version;
};
struct id
{
char id;
char platform;
};
struct data
{
struct id idv;
struct signature sig;
char data[100];
};
static void receivedata(struct data *d);
static struct signature *extractsignature(struct data *d);
static struct id *extractid(struct data *d);
int main(int argc, char *argv[])
{
/* Actual line in book is :
* struct data *img; with no memory allocation or assignment to NULL.
* Had errors so i allocated memory on the heap before passing the value to
* Receivedata(); */
struct data *img = malloc(sizeof(struct data));
receivedata(img);
/* Actual line in book is :
* struct id *idval = extractid(&img);
* struct signature *sig = extractsignature(&img);
* This is obviously erroneous because &img is a pointer
* to a pointer (struct data**) which is not the data type for
* the extract functions' argument */
struct id *idval = extractid(img);
struct signature *sig = extractsignature(img);
printf("For signature:\n");
printf("sign = %c", sig->sign);
printf(" version = %c\n\n", sig->version);
printf("For id:\n");
printf("id = %c", idval->id);
printf(" platform = %c", idval->platform);
printf("\ndata = %s", img->data);
return 0;
}
static struct signature *extractsignature(struct data *d)
{
struct signature *sig = (struct signature *)d;
return sig;
}
static struct id *extractid(struct data *d)
{
struct id *idv = (struct id *)d;
return idv;
}
static void receivedata(struct data *d)
{
struct data *dptr = d;
char *ch = "CODING IS COOL!";
dptr->sig.sign = 's';
dptr->sig.version = '1';
dptr->idv.id = 'i';
dptr->idv.platform = 'p';
strncpy(dptr->data, ch, strlen(ch));
return;
}
我想了解的是函数 extractid()
和 extraxtsignature()
内部的转换,因为看起来我们正在转换 struct data *
以便检索其各个成员。我运行程序,得到的是 sig 成员和 id 成员的 struct data
第一个成员的值。以下是 struct id
在 struct data
中排在第一位时的输出:
For signature:
sign = i version = p
For id:
id = i platform = p
data = CODING IS COOL!
当 struct signature
是第一个元素时:
For signature:
sign = s version = 1
For id:
id = s platform = 1
data = CODING IS COOL!
最后,当 char data[100]
是第一个元素时:
For signature:
sign = C version = O
For id:
id = C platform = O
data = CODING IS COOL!
能否请您解释一下这种类型的转换、何时使用它以及最佳实践。非常感谢。
最佳答案
struct data
{
struct id idv;
struct signature sig;
char data[100];
};
对于上面的定义,下面的extractid
函数是有效的,会得到正确的结果。
static struct id *extractid(struct data *d)
{
struct id *idv = (struct id *)d;
return idv;
}
这是因为,struct id
是struct data
的第一个成员。所以,当你有 struct data *d
时,d
指向 struct data
的起始地址并且与第一个成员 struct id
。
因此,如果您为结构的第一个成员进行强制转换,那么按照您上面提供的代码是正确的。
关于c - 类型转换结构指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35060614/