简体   繁体   English

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

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

I'm learning processes and in the following code snippet:我正在学习流程和以下代码片段:

/* 
 * 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);
    }
}

when I trace WIFEXITED function definition this is what I've got:当我跟踪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 */

I have two questions:我有两个问题:

  1. Why use mask 0177 instead of 0b1111111 , I've seen it many times, what's the benefits of using octal number over other formats?为什么使用掩码0177而不是0b1111111 ,我已经见过很多次了,使用八进制数比其他格式有什么好处? Personally I find binary more intuitive.我个人觉得二进制更直观。
  2. What's the meaning of (*(int *)&(w)) ? (*(int *)&(w))什么意思?

Thanks!谢谢!

Binary constants such as 0b1111111 are not defined by the C standard and were introduced as an extension by some C implementations somewhat late, so earlier code necessarily used octal and hexadecimal constants, and programmers became accustomed to them.诸如0b1111111类的二进制常量不是由 C 标准定义的,而是被一些 C 实现作为扩展引入的,有些晚了,所以早期的代码必然使用八进制和十六进制常量,程序员已经习惯了它们。 Additionally, octal is more compact, and I can count the number of set bits in 0177 more easily than in 0b1111111 .此外,八进制更紧凑,与0b1111111相比,我可以更轻松地计算0177中设置的位数。 One quickly becomes accustomed to knowing that 7 means three bits set.人们很快就会习惯于知道7表示设置了三位。

In (*(int *)&(w)) , &(w) takes the address of the object designated by w .(*(int *)&(w))&(w)获取由w指定的对象的地址。 Then (int *) converts that address from the type “pointer to type of w” to “pointer to int”.然后(int *)将该地址从“指向 w 类型的指针”类型转换为“指向 int 类型的指针”。 Then * dereferences that pointer, nominally producing an int value.然后*取消引用该指针,名义上产生一个int值。

The intent is to access the first bytes of w as if they were an int , effectively getting the raw bits that are in w instead of interpreting it as a structure or whatever other type it is.目的是像访问int一样访问w的第一个字节,有效地获取w的原始位,而不是将其解释为结构或任何其他类型。 This is called aliasing .这称为混叠

Aliasing in this way is not supported by the C standard, but many C implementations allow it, and the code you show appear to have been written specifically for such an implementation. C 标准不支持这种方式的别名,但许多 C 实现允许它,并且您显示的代码似乎是专门为这种实现编写的。

A supported way to get the raw bits of an object is to copy bytes individually, as with:获取对象原始位的一种受支持的方法是单独复制字节,如下所示:

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

Although this looks like a function call, good compilers recognize it as a request to access the first bytes of w as if they were an int and optimize it.尽管这看起来像一个函数调用,但优秀的编译器会将其识别为访问w的第一个字节的请求,就好像它们是一个int并对其进行优化。 The result may be a single load instruction.结果可能是单个加载指令。 However, wrapping this into a macro that produces the int as a value involves some complications, which I will leave for further discussion elsewhere.然而,将它包装到一个产生int作为值的宏中会涉及一些复杂性,我将在别处进一步讨论。 (You can ask a new question about that, if desired.) (如果需要,您可以就此提出一个新问题。)

1 Why use mask 0177 instead of 0b1111111 ... ? 1 为什么使用掩码 0177 而不是 0b1111111 ... ?

(This answer only addresses this portion of your question) (此答案仅解决您问题的这一部分)

Because 0b1111111 is not a C integer constant per 6.4.4.1 Integer constants :因为0b1111111不是每个6.4.4.1 整数常量的 C 整数常量

Syntax句法

1 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

Description描述

2 An integer constant begins with a digit, but has no period or exponent part. 2 整数常量以数字开头,但没有句点或指数部分。 It may have a prefix that specifies its base and a suffix that specifies its type.它可能有一个指定其基础的前缀和一个指定其类型的后缀。

3 A decimal constant begins with a nonzero digit and consists of a sequence of decimal digits. 3 十进制常数以非零数字开头,由一串十进制数字组成。 An octal constant consists of the prefix 0 optionally followed by a sequence of the digits 0 through 7 only.八进制常量由前缀 0 组成,可选地后跟仅数字 0 到 7 的序列。 A hexadecimal constant consists of the prefix 0x or 0X followed by a sequence of the decimal digits and the letters a (or A) through f (or F) with values 10 through 15 respectively.十六进制常量由前缀 0x 或 0X 后跟十进制数字序列和字母 a(或 A)到 f(或 F)组成,其值分别为 10 到 15。

By standard, C only supports decimal, octal, and hexadecimal integer constants.按照标准,C 仅支持十进制、八进制和十六进制整数常量。

    1. It has the advantage of not requiring any extra symbols as digits (the hexadecimal system is base-16 and therefore needs six additional symbols beyond 0–9).它的优点是不需要任何额外的符号作为数字(十六进制系统是 base-16,因此需要 0-9 之外的六个额外符号)。 It is also used for digital displays.它也用于数字显示。
  1. You are trying to convert it to integer pointer and referencing the value from it.您正在尝试将其转换为整数指针并从中引用值。

About your first question: Binary literals are not officially part of the C standard (and are only part of C++ since C++14), hence using octal literals instead of using them can improve portability.关于您的第一个问题:二进制文字不是 C 标准的正式组成部分(并且自 C++14 以来只是 C++ 的一部分),因此使用八进制文字而不是使用它们可以提高可移植性。

About your second question: &w takes the address of w , which is then converted to a pointer to an int ( (int*)&w ) which is dereferenced.关于第二个问题: &w采用的地址w ,然后将其转换成一个指向一个int( (int*)&w这是间接引用)。 What that effectively does is read memory from w as though w were an int .有效的做法是从w读取内存,就好像w是一个int

you should check this link it will help you to solve any question by using (Clockwise/Spiral Rule)您应该检查此链接,它将帮助您使用(顺时针/螺旋规则)解决任何问题

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

( (int )&(w)) firstly &w means address of w where & is address operator then (int *) means creating pointer to integer so ( till this step you have pointer which point to address of w) finally * before this pointer means (you accessed the value of w ) ( (int )&(w)) 首先 &w 表示 w 的地址,其中 & 是地址运算符,然后 (int *) 表示创建指向整数的指针,因此(直到这一步您有指向 w 的地址的指针)最后 * 在此指针之前意味着(您访问了 w 的值)

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

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