C语言类型转换

标签 c casting

我现在了解套接字,我发现它非常令人困惑,因为转换结构。

指南说在 sockaddr_in 中包含 8 位以将其与 sockaddr 进行比较。

所以我的问题是为什么要这样做,我的意思是当你进行转换时,你不会将字符大小与 int 进行比较

例如你这样做

char a[1]='1';
int b=(int)a;

而不是

char a[2]='1';//compare to size of int
int b=(int)a; 

那么它是如何工作的呢?

铸件结构有什么不同吗? 如果是的话为什么?

最佳答案

将指针传递给结构时,接收它的函数可能会尝试访问其所有字段中的任何一个。

如果您收到一个struct Something *,您希望可以读取您收到的指针后面的任何sizeof(struct Something)字节。因此,不在您自己的 struct 中保留这些字节将使它们不兼容 - 每当函数尝试访问您尚未分配的字节时,它将访问非保留内存,因此它可以是段错误,或者可能损坏他人的结构数据。

<小时/>

看看这个程序:

#include <stdlib.h>
#include <stdio.h>

struct __attribute__ ((__packed__)) pair {
        short first;
        char second;
        long int third;
        int forth;
        char last;
};

void main(void) {
        struct pair myPair;
        printf("myPair         is at 0x%x\n", &myPair);
        printf("myPair.first   is at 0x%x\n", &(myPair.first));
        printf("myPair.second  is at 0x%x\n", &(myPair.second));
        printf("myPair.third   is at 0x%x\n", &(myPair.third));
        printf("myPair.forth   is at 0x%x\n", &(myPair.forth));
        printf("myPair.last    is at 0x%x\n", &(myPair.last));
}

以及示例输出:

myPair         is at 0xabbd0aa0
myPair.first   is at 0xabbd0aa0
myPair.second  is at 0xabbd0aa2
myPair.third   is at 0xabbd0aa3
myPair.forth   is at 0xabbd0aab
myPair.last    is at 0xabbd0aaf

我们在这里学到的是,每个字段都存储在内存中前一个字段的旁边,更准确地说,前一个字段右侧的 sizeof(previous_field) 个字节(当 struct 打包 - 请参阅 this 了解为什么打包,但这是理想情况)。

因此,假设我们想创建另一个与此兼容的struct。如果我们创建类似的东西:

struct __attribute__ ((__packed__)) small_pair {
        long int first;
        char second;
        int third;
        char forth;
};

我们可以通过强制转换将 structsmall_pair * 传递给任何需要 structpair* 的函数:

void my_function(struct pair *);

void main(void) {
    struct small_pair my_small_pair;
    // ...
    my_function((struct pair*) &my_small_pair);
    // ...
}

void my_function(struct pair *a_pair) {
    //...
    printf("Second character of pair is %c\n", a_pair->second);
    //...
    printf("Last character of pair is %c\n", a_pair->last);
    //...
}

编译后,访问a_pair->second就是“读取结构体开始后两个字节的一个字节”(0xabbd0aa2 - 0xabbd0aa0 = 2)。因此,这将是 structsmall_pair 的字段 first 的第三个字节,无论它具有哪个值。

但是,a_pair->last 又如何呢?它是结构体开始后的 0xf (15) 个字节,但显然超出了它的空间(sizeof(structsmall_pair) 只是 14)。

所以这取决于变量加载到内存中的方式,但显然我们不会引用我们想要的值。最好的情况是当该地址超出我们的进程空间时,我们会收到段错误,并且程序中止。但很可能在内存的该位置声明了另一个变量,并且我们将读取/写入与我们想要的不同的变量,留下谁知道什么结果。

因此,如果我们只是在 structsmall_pair 的末尾添加另一个 2 字节长的字段,我们保证 structpair 的每个可能的引用仍然会存在。在我们自己的struct中是正确的,因此它们将在内存级别兼容。

然后,它仍然保留了语义级别的兼容性,但这是一个不同的故事:)

关于C语言类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13546564/

相关文章:

c - recvfrom无限接收问题

C - 使用文本文件

c++ - 具有单继承的类的指针转换偏移

angular - 将数字类型转换为 BigDecimal TypeScript(Angular)

grails - Grails-条件查询中的 'in'节点-groovy.lang.IntRange无法转换为java.lang.Integer

创建命令来运行并向 Windows 应用程序提供输入

c - 如何使用 C 从进程状态文件中获取 UID

c - asm 内联函数中的 "@"是什么意思?

sql - 尝试创建大型动态查询时,不断被截断

c++ - 在不同类型的对象指针之间切换