c - 类型转换结构指针

标签 c pointers struct

大家好。我正在使用名为 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 idstruct 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 idstruct data 的第一个成员。所以,当你有 struct data *d 时,d 指向 struct data 的起始地址并且与第一个成员 struct id

因此,如果您为结构的第一个成员进行强制转换,那么按照您上面提供的代码是正确的。

关于c - 类型转换结构指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35060614/

相关文章:

c - 在线程中执行 malloc

c - C中的空指针

c - C 中的数组指针

c++ - 如何对结构成员使用指针

c++ - 使用没有默认构造函数的常量字段初始化结构数组

c - 内置函数的隐式声明不兼容 ‘malloc’

c - 在解释器创建方面需要一些指导

c - C 中的单行 if 语句 - 哪些语句受到影响?

c - 有没有办法限制指针被特定函数修改?

go - 更新作为接口(interface)传递的函数内部的结构字段