struct shape
、struct rectangle
和struct triangle
类型的指针之间进行类型转换。#include <stdio.h>
#include <stdlib.h>
#include <time.h>
enum { RECTANGLE, TRIANGLE, MAX };
struct shape {
int type;
};
struct rectangle {
int type;
int x;
int y;
};
struct triangle {
int type;
int x;
int y;
int z;
};
struct shape *get_random_shape()
{
int type = rand() % MAX;
if (type == RECTANGLE) {
struct rectangle *r = malloc(sizeof (struct rectangle));
r->type = type;
r->x = rand() % 10 + 1;
r->y = rand() % 10 + 1;
return (struct shape *) r;
} else if (type == TRIANGLE) {
struct triangle *t = malloc(sizeof (struct triangle));
t->type = type;
t->x = rand() % 10 + 1;
t->y = rand() % 10 + 1;
t->z = rand() % 10 + 1;
return (struct shape *) t;
} else {
return NULL;
}
}
int main()
{
srand(time(NULL));
struct shape *s = get_random_shape();
if (s->type == RECTANGLE) {
struct rectangle *r = (struct rectangle *) s;
printf("perimeter of rectangle: %d\n", r->x + r->y);
} else if (s->type == TRIANGLE) {
struct triangle *t = (struct triangle *) s;
printf("perimeter of triangle: %d\n", t->x + t->y + t->z);
} else {
printf("unknown shape\n");
}
return 0;
}
这是输出结果。
$ gcc -std=c99 -Wall -Wextra -pedantic main.c
$ ./a.out
perimeter of triangle: 22
$ ./a.out
perimeter of triangle: 24
$ ./a.out
perimeter of rectangle: 8
您可以看到,程序编译并且运行时没有任何警告。我正试图理解是否可以将
struct shape
的指针强制转换为struct rectangle
的指针,反之亦然,即使这两个结构体的大小不同。如果您的答案是这是无效的,请考虑网络编程书籍通常会根据套接字家族(AF_INET与AF_INET6)在
struct sockaddr *
、struct sockaddr_in *
和struct sockaddr_in6 *
指针之间进行类型转换,然后请解释为什么在struct shape *
的情况下这样的类型转换是可以的,但在上述情况下不可以。以下是使用struct sockaddr *
进行类型转换的示例。#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
int main()
{
struct addrinfo *ai;
if (getaddrinfo("localhost", "http", NULL, &ai) != 0) {
printf("error\n");
return EXIT_FAILURE;
}
if (ai->ai_family == AF_INET) {
struct sockaddr_in *addr = (struct sockaddr_in *) ai->ai_addr;
printf("IPv4 port: %d\n", addr->sin_port);
} else if (ai->ai_family == AF_INET6) {
struct sockaddr_in6 *addr = (struct sockaddr_in6 *) ai->ai_addr;
printf("IPv6 port: %d\n", addr->sin6_port);
}
return 0;
}
这段代码可以正常编译和运行。此外,根据关于套接字编程的书籍,这也是推荐的编写此类程序的方式。
$ gcc -std=c99 -D_POSIX_SOURCE -Wall -Wextra -pedantic foo.c
$ ./a.out
IPv6 port: 20480
union
。 - edmzr->type
意味着(*r).type
,而*r
违反了规则;另一些人(包括我)认为它不是因为r->type
是唯一访问的内容,它是类型为int
的内容并且只读取了一个int
。 - M.M