~C中的接线员

~C中的接线员,c,operators,C,Operators,这个程序的输出是-13。我从来没有完全理解C中的~运算符。为什么它会将-13作为输出?如何将~运算符限制为一个数字的4位 #include<stdio.h> #include<conio.h> int main() { int a = 12; a = ~a; printf("%d",a); getch(); return; } #包括 #包括 int

这个程序的输出是-13。我从来没有完全理解C中的~运算符。为什么它会将-13作为输出?如何将~运算符限制为一个数字的4位

    #include<stdio.h>
    #include<conio.h>
    int main()
    {
        int a = 12;
        a = ~a;
        printf("%d",a);
        getch();
        return;
    } 
#包括
#包括
int main()
{
INTA=12;
a=~a;
printf(“%d”,a);
getch();
返回;
} 
它是一个按位运算符(补码),其工作方式如下:

~00000101 // 5
=11111010 // 250
因此,1变为0,反之亦然,但在某些情况下,符号位被激活,您将得到意外的结果

这是一个按位运算符(一的补码),其工作方式如下:

~00000101 // 5
=11111010 // 250

因此,1变为0,反之亦然,但在某些情况下,符号位被激活,您将得到意外的结果

要将效果限制在指定的位数,只需使用按位掩码,例如:

#include <stdio.h>

int main(void) {
    int a = 16;             /* 10000 in binary */
    int b = ~a;             /* Will interpret b as -17 in two's complement */
    int c = (a & ~0xF) | (~a & 0xF); /* Will limit operator to rightmost 4 bits,
                                        so 00000 becomes 01111, and c will become
                                        11111, not 11...101111, so c will be 31     */

    printf("a is %d, b is %d, c is %d\n", a, b, c);
    return 0;
}

要将效果限制在指定的位数,只需使用位掩码,例如:

#include <stdio.h>

int main(void) {
    int a = 16;             /* 10000 in binary */
    int b = ~a;             /* Will interpret b as -17 in two's complement */
    int c = (a & ~0xF) | (~a & 0xF); /* Will limit operator to rightmost 4 bits,
                                        so 00000 becomes 01111, and c will become
                                        11111, not 11...101111, so c will be 31     */

    printf("a is %d, b is %d, c is %d\n", a, b, c);
    return 0;
}

~运算符充当二进制NOT,也就是说,它翻转数字中的所有位。有符号整数中的负数存储为。

运算符充当二进制,而不是,也就是说,它翻转数字中的所有位。有符号整数中的负数存储为二进制的。

(12)10
(1100)2

波浪号是位补运算符,它使
1100
-->
0011
。但是,如果您在32位平台上工作,我们得到的实际结果是:

0000 0000 0000 0000 0000 0000 0000 1100
其按位补码为:

1111 1111 1111 1111 1111 1111 1111 0011
|
现在,因为最左边的位是符号,所以数字变为负数。如果使用unsigned int,您将能够更好地理解发生了什么:

unsigned int a = 12;
a = ~a;
将提供:

1111 1111 1111 1111 1111 1111 1111 0011
在二进制中是4294967283
(12)10
,它是
(1100)2

波浪号是位补运算符,它使
1100
-->
0011
。但是,如果您在32位平台上工作,我们得到的实际结果是:

0000 0000 0000 0000 0000 0000 0000 1100
其按位补码为:

1111 1111 1111 1111 1111 1111 1111 0011
|
现在,因为最左边的位是符号,所以数字变为负数。如果使用unsigned int,您将能够更好地理解发生了什么:

unsigned int a = 12;
a = ~a;
将提供:

1111 1111 1111 1111 1111 1111 1111 0011

这是
4294967283

运算符
~
是C中的逻辑
而不是
,即当应用于整数时,它会翻转其二进制表示形式的每一个整数。请注意,在中仅将整数定义为
int
将使其成为无符号整数。这意味着第一个字符用作符号位。因为负片的定义是
-a=~a+1
,所以可以看到
~a=-a-1
。如果您只想翻转
int
的最后4位(或者更一般地说是最后k位),您可以这样做

int k = 4;
int mask = (1 << k) - 1;
int b = a ^ mask;
intk=4;

整数掩码=(1运算符
~
是C中的逻辑
而不是
,即当应用于整数时,它会翻转其二进制表示形式的每一个部分。请注意,在中将整数定义为
int
将使其成为无符号整数。这意味着第一个整数用作符号位。因为负数定义为
-a=~a+1
您可以看到
~a=-a-1
。如果您只想翻转
int
的最后4位(或者更一般地说是最后k位),您可以这样做

int k = 4;
int mask = (1 << k) - 1;
int b = a ^ mask;
intk=4;

int mask=(1读C99 6.5.33,一元算术运算符)。~运算符的结果是其(提升的)操作数的按位补码(即,当且仅当未设置转换的操作数中的对应位时,才设置结果中的每一位)。对操作数执行整数升级,结果为升级类型。如果升级类型为无符号类型,则表达式~E等于该类型中可表示的最大值减去E。”关于整数提升的部分将带您进入C99 6.3.1.1,这有点令人兴奋,但您提出了要求。您得到-13,因为系统使用两个补码表示负数,而
~
运算符则给您一个补码。两个补码定义为一的补码加一。阅读C99 6.5.33,一元算术o运算符的结果是其(提升的)操作数的按位补码(即,当且仅当未设置转换的操作数中的对应位时,才设置结果中的每一位)。对操作数执行整数升级,结果为升级类型。如果升级类型为无符号类型,则表达式~E等于该类型中可表示的最大值减去E。”关于整数提升的部分将带您进入C99 6.3.1.1,这有点令人兴奋,但您提出了问题。您得到-13,因为系统使用两个补码表示负数,而
~
运算符则给您一个补码。两个补码定义为一的补码加一。您非常接近。但是,您将需要d在执行
a |(~a&0xF)之前清除最右边的四位
。它对您有效的原因是,您正在使用
a
作为
16
,二进制格式是
10000
。使用
a
作为
17
运行您的程序,二进制格式是
10001
,您仍然可以看到
31
的输出。但是,您需要清除最右边的四个b这是在你做
a|(~a&0xF)
之前。它对你有效的原因是,你有
a
作为
16
,二进制是
10000
。用
a
作为
17
运行你的程序,二进制是
10001
,你仍然会看到输出是
31