Learning summary (bit operator; three ways to loop input; three ways to exchange two variable values; print the binary corresponding to the number; the difference between unsigned int and int; change the specific digit 0/1; && and || Continuous operation (combined with front and rear))

1. Print the binary corresponding to the number (and count the number of occurrences of 1)

For integers and floating-point numbers, they are stored by their two’s complement when they are stored in the computer, including operations on numbers, which essentially operate on their two’s complement;

On a 32-bit machine, an integer corresponds to 32 binary bits. For positive numbers, its original code = inverse code = complement code; for negative numbers, its inverse code = original code (invert sign bit by bit), complement code = inverse code + 1;

The corresponding binary for printing is, the core idea is to use: bitwise AND & amp; operator & amp;1

Specific digits: sum 1 & amp;, if it is 0 originally, it will be 0 after & amp;, if it is 1, it will still be 1 after & amp;;

Get an integer corresponding to the number of 1 in binary in memory
Two methods (more than one method)
 
/*method one*/
int print_binary(unsigned x)
{
int count = 0;
unsigned int o = 1 << 31;//Must be set to unsigned instead of comparing from the first
int i = 0;
for (i = 0; i < 32; i ++ )
{
if (o & x)
{
printf("1");
count + =1;
}
else
{
printf("0");
}
o = o >> 1;
}
return count;
}
int main()
{
unsigned int i;
scanf("%u", &i);

/*Count the number of occurrences of 1*/
unsigned int ret = print_binary(i);
printf("\\
1 occurrence times=%u\\
", ret);

return 0;
}
 

/*Method Two*/
int print_binary(unsigned x)
{
unsigned int o = 1;
int i = 0;
int count = 0;
for (i = 0; i < 32; i ++ )
{
if (x & o)
{
printf("1");
count += 1;
}
else
{
printf("0");
}
x = x >> 1;
}
return count;
}
int main()
{
unsigned int i;
scanf("%u", &i);
unsigned int ret = print_binary(i);

printf("\\
1 occurrence times=%u\\
", ret);

return 0;
}


/*Method 3*/
#include <stdio.h>
int main()
{
int num = 15;
int i = 0;
int count = 0;//count
for (i = 0; i < 32; i ++ )
{
if (num & amp; (1 << i)) // & amp; will compare all binary bits at a time. 1 is 0 except the last bit is 1
count + + ;
}
printf("Number of 1s in binary = %d\\
", count);
return 0;
}

Supplement: The difference between unsigned int and Int (detailed explanation)

  1. The storage data range is different
    1. Unsigned int is an unsigned integer, that is, the first digit can only be 0, that is, it can only represent non-negative integers. (32-bit machine) range is usually: 0~4294967295
    2. Int is a signed integer, that is, the first digit is 0 to indicate a positive number, and the first digit is 1 to indicate a negative number. (32-bit machines) the range is usually:- 2147483648~2147483647

2. Different operation rules

In the C language, for signed integer types, the sign of the value is considered when performing arithmetic operations, so overflow or negative overflow may occur. For unsigned integer types, the sign of the value is not considered when performing arithmetic operations, so negative overflow cannot occur, but unsigned integer overflow may occur.

For example, adding -1 to 1 yields 0 for an `int` type, but adding 4294967295 (the largest unsigned integer) to 1 yields 0 for an `unsigned int` type.

Summary: If you want to store non-negative integers or handle larger unsigned data types, you should use the “unsigned int” type; if you need to store positive and negative numbers or handle signed data, you should use “int”; at the same time, It should also be noted that both types carry the danger of overflow;

2. Three ways to cycle input

/*Three methods of loop input*/

/*Method 1: Use the return value of scanf() to read the number of characters*/
int main()
{
    int i = 0;
    while (scanf("%d", &i) == 1)
    {
        i = pow(i,3);
        printf("%d\\
", i);
    }
    return 0;
}


/*Method 2: Use EOF*/
int main()
{
    int i = 0; //The EOF returned by the scanf function failed to read
    while (scanf("%d", & amp;i)!= EOF) //EOF=end of file(=-1), press ctrl + z to end the cycle (press three times in vs)
    {
        i = pow(i, 3);
        printf("%d\\
", i);
    }
    return 0;
}

/*Method 3: Use the ~ operator*/
int main()
{
    int i = 0; //-1 :100000000000000000000000000000001
    while (~scanf("%d", & amp;i)) //inverse code: 1111111111111111111111111111110
    { // Complement code: 1111111111111111111111111111111
        i = pow(i,3); //~(-1)=0
        printf("%d\\
", i); //If the reading fails, return EOF(-1), invert to 0, just the end of the loop
    }
    return 0;
}

3. Three ways to exchange two variable values

/*Three methods of exchanging two integers and their disadvantages*/

/*Method 1: Create a temporary variable*/
The int main() method is cumbersome
{
int a = 10;
int b = 20;
int temp = 0;//temporary variable

//Assignment process
temp = a;
a = b;
b = temp;

printf("a=%d b=%d", a, b);

return 0;
}

/*Method 2: Use the ^ operator*/ //Not so easy to think about
                                 Only for binary changes, there is no risk of overflow
int main()
{
int a = 10;
int b = 20;
int temp = 0;//temporary variable

//Assignment process
a = a ^ b; // just understand the two most basic ^ operations
b = a ^ b; //1:a ^ a = 0; XOR itself = 0 (because every bit is the same)
a = a ^ b; //2:0 ^ a = a; 0 XOR a number = XOR number (0^1=1 0^0=0)

printf("a=%d b=%d", a, b);

return 0;
}

/*Method 3*/ /*Create a c variable, store the sum of a + b, and then complete the assignment by subtraction*/
                   It is easy to think, but c may overflow (exceeding the maximum value of the int type), resulting in data loss
int main()
{
int a = 10;
int b = 20;
int temp = 0;//temporary variable

//Assignment process
int c = a + b;
a = c - a;
b = c - b;

printf("a=%d b=%d", a, b);

return 0;
}

4. Change specific digits 0/1

Core idea: use the & amp; operator and the ~ operator ( & amp; : both false and false ~ : both true and true)

/*Change the 0/1 of a specific digit*/

int main()
{
    int a = 13;
    //00000000000000000000000000001101 Change the fifth 0 to 1, 0^1=1, the other bits remain unchanged
    //00000000000000000000000000010000
    //000000000000000000000000000011101
    a = a^(1 << 4);
    printf("%d\\
", a); //=29
    // change a back
    //00000000000000000000000000011101 Change the fifth 1 to 0,1 & amp;0=0, the other bits remain unchanged
    //111111111111111111111111101111 =~(1<<4)
    a = a & (~(1 << 4));
    printf("%d\\
", a);
    
    return 0; //It’s good to understand, & amp; is false, so it is easy to appear 0, ^ is true, so it is easy to appear 1
}

5. Continuous operation of & amp; & amp; and || (combined with front and back)

Core idea: & amp; & amp; as long as 0 (false) is encountered, there is no need to calculate later, it is a broken circuit; similarly, as long as || encounters 1 (true), there will be a broken circuit later, and no further calculation is required;

code show as below:

// & amp; ^Concerned about the change of the binary bit unary operator
// & amp; & amp; || only focus on true and false Logical operators, if the result is true, return 1
// & amp; & amp; one false and one false || one true and two true


int main()
{
int a = 1;
int b = 2;
int c = 3; /*a-- is to perform the operation of & amp; & amp; first, and then perform a=a-1*/
int i = a-- & amp; & amp; + + b & amp; & amp; c + + ;
printf("%d %d %d", a, b, c);//0 3 4

return 0;
}

int main()
{
int a = 1;
int b = 2;
int c = 3; /*a-- is to execute & amp; first, then a=a-1*/
int i = a + + || + + b || c + + ;
printf("%d %d %d", a, b, c);//2 2 3

return 0;
}

Note: & amp;, ^ and & amp; & amp;, || are not the same thing at all; the former is a unary operator, which performs binary conversion; the latter is a logical operator, which performs logical judgment , only return 0 or 1;