繁体   English   中英

(*(int *)&(w)) 在 c 编程中是什么意思?

[英]What does (*(int *)&(w)) mean in c programming?

我正在学习流程和以下代码片段:

/* 
 * fork10 - Synchronizing with multiple children (wait)
 * Reaps children in arbitrary order
 * WIFEXITED and WEXITSTATUS to get info about terminated children
 */
void fork10()
{
    pid_t pid[N];
    int i, child_status;

    for (i = 0; i < N; i++)
    if ((pid[i] = fork()) == 0) {
        exit(100+i); /* Child */
    }
    for (i = 0; i < N; i++) { /* Parent */
        pid_t wpid = wait(&child_status);
        if (WIFEXITED(child_status))
            printf("Child %d terminated with exit status %d\n", wpid, WEXITSTATUS(child_status));
        else
            printf("Child %d terminate abnormally\n", wpid);
    }
}

当我跟踪WIFEXITED函数定义时,这就是我所得到的:

#define WIFEXITED(x)    (_WSTATUS(x) == 0)
#define _WSTATUS(x) (_W_INT(x) & 0177)
#define _W_INT(w)   (*(int *)&(w))  /* convert union wait to int */

我有两个问题:

  1. 为什么使用掩码0177而不是0b1111111 ,我已经见过很多次了,使用八进制数比其他格式有什么好处? 我个人觉得二进制更直观。
  2. (*(int *)&(w))什么意思?

谢谢!

诸如0b1111111类的二进制常量不是由 C 标准定义的,而是被一些 C 实现作为扩展引入的,有些晚了,所以早期的代码必然使用八进制和十六进制常量,程序员已经习惯了它们。 此外,八进制更紧凑,与0b1111111相比,我可以更轻松地计算0177中设置的位数。 人们很快就会习惯于知道7表示设置了三位。

(*(int *)&(w))&(w)获取由w指定的对象的地址。 然后(int *)将该地址从“指向 w 类型的指针”类型转换为“指向 int 类型的指针”。 然后*取消引用该指针,名义上产生一个int值。

目的是像访问int一样访问w的第一个字节,有效地获取w的原始位,而不是将其解释为结构或任何其他类型。 这称为混叠

C 标准不支持这种方式的别名,但许多 C 实现允许它,并且您显示的代码似乎是专门为这种实现编写的。

获取对象原始位的一种受支持的方法是单独复制字节,如下所示:

int b;
memcpy(&b, &w, sizeof b);

尽管这看起来像一个函数调用,但优秀的编译器会将其识别为访问w的第一个字节的请求,就好像它们是一个int并对其进行优化。 结果可能是单个加载指令。 然而,将它包装到一个产生int作为值的宏中会涉及一些复杂性,我将在别处进一步讨论。 (如果需要,您可以就此提出一个新问题。)

1 为什么使用掩码 0177 而不是 0b1111111 ... ?

(此答案仅解决您问题的这一部分)

因为0b1111111不是每个6.4.4.1 整数常量的 C 整数常量

句法

1

 integer-constant: decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt decimal-constant: nonzero-digit decimal-constant digit octal-constant: 0 octal-constant octal-digit hexadecimal-constant: hexadecimal-prefix hexadecimal-digit hexadecimal-constant hexadecimal-digit hexadecimal-prefix: one of 0x 0X nonzero-digit: one of 1 2 3 4 5 6 7 8 9 octal-digit: one of 0 1 2 3 4 5 6 7 hexadecimal-digit: one of 0 1 2 3 4 5 6 7 8 9 abcdef ABCDEF integer-suffix: unsigned-suffix long-suffixopt unsigned-suffix long-long-suffix long-suffix unsigned-suffixopt long-long-suffix unsigned-suffixopt unsigned-suffix: one of u U long-suffix: one of l L long-long-suffix: one of ll LL

描述

2 整数常量以数字开头,但没有句点或指数部分。 它可能有一个指定其基础的前缀和一个指定其类型的后缀。

3 十进制常数以非零数字开头,由一串十进制数字组成。 八进制常量由前缀 0 组成,可选地后跟仅数字 0 到 7 的序列。 十六进制常量由前缀 0x 或 0X 后跟十进制数字序列和字母 a(或 A)到 f(或 F)组成,其值分别为 10 到 15。

按照标准,C 仅支持十进制、八进制和十六进制整数常量。

    1. 它的优点是不需要任何额外的符号作为数字(十六进制系统是 base-16,因此需要 0-9 之外的六个额外符号)。 它也用于数字显示。
  1. 您正在尝试将其转换为整数指针并从中引用值。

关于您的第一个问题:二进制文字不是 C 标准的正式组成部分(并且自 C++14 以来只是 C++ 的一部分),因此使用八进制文字而不是使用它们可以提高可移植性。

关于第二个问题: &w采用的地址w ,然后将其转换成一个指向一个int( (int*)&w这是间接引用)。 有效的做法是从w读取内存,就好像w是一个int

您应该检查此链接,它将帮助您使用(顺时针/螺旋规则)解决任何问题

http://c-faq.com/decl/spiral.anderson.html?fbclid=IwAR3V_KR4VwO33UvbO4LgN3AIW_79QBWAR9qHO2KHyyJgEuIKiFQOQTCec5U

( (int )&(w)) 首先 &w 表示 w 的地址,其中 & 是地址运算符,然后 (int *) 表示创建指向整数的指针,因此(直到这一步您有指向 w 的地址的指针)最后 * 在此指针之前意味着(您访问了 w 的值)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM