学习总结(位操作符;循环输入的三种方式;交换两个变量值的三种方法;打印数字对应的二进制;unsigned int 与int 的区别;改变特定位数0/1;&&和||的连续操作(与前置,后置结合))

简介: 学习总结(位操作符;循环输入的三种方式;交换两个变量值的三种方法;打印数字对应的二进制;unsigned int 与int 的区别;改变特定位数0/1;&&和||的连续操作(与前置,后置结合))

1.打印数字对应的二进制(并统计1出现的次数)

       对于整数和浮点数来说,在计算机存储时都是通过其二进制的补码进行存储的,包括对数字的操作,本质上都是操作其二进制补码;

       在32位机器下,一个整数对应着32个二进制位。对于正数来说,其原码=反码=补码;对于负数来说,反码=原码(除符号位按位取反),补码=反码+1;

 

       打印对应的二进制为,核心思想是利用:按位与&操作符  &1

特定位数:和1&,如果原先是0,&之后还是0,如果是1,&后还是1;

获得一个整数在内存中对应二进制中1的个数
两种方法(不止一种方法)
/*方法一*/
int print_binary(unsigned x)
{
  int count = 0;
  unsigned int o = 1 << 31;//一定要设置为unsigned不是从首位开始比较
  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);
  /*统计1出现的次数*/
  unsigned int ret = print_binary(i);
  printf("\n1出现的次数为=%u\n", ret);
  return 0;
}
/*方法二*/
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("\n1出现的次数为=%u\n", ret);
  return 0;
}
/*方法3*/
#include <stdio.h>
int main()
{
  int num = 15;
  int i = 0;
  int count = 0;//计数
  for (i = 0; i < 32; i++)
  {
    if (num & (1 << i))  // & 一次会比较所有的二进制位   1是除了最后一位是1,其他都是0
      count++;
  }
  printf("二进制中1的个数 = %d\n", count);
  return 0;
}

补充:unsigned int 与Int的区别(详解)

  1. 存储数据范围不同
  1. Unsigned int 是无符号 整型,即首位只能为0,也即只能表示非负整数。(32位机器)范围通常为:0~4294967295
  2. Int 是有符号整形,即首位为0表示正数,首位为1,表示负数,(32位机器)范围通常为:-2147483648~2147483647

   2.运算规则不同

       在C语言中,对于有符号整数类型,进行算术运算时会考虑数值的符号,因此可能会发生溢出或者负数溢出的情况。而对于无符号整数类型,进行算术运算时不考虑数值的符号,因此不会发生负数溢出,但可能会发生无符号整数溢出。

例如,对于`int`类型,-1和1相加会得到0,但对于`unsigned int`类型,4294967295(即无符号的最大整数)和1相加会得到0。

总结:如果想存储非负整数或者处理更大的无符号数据类型,则应该使用”unsigned int”类型;如果需要存储正负正数或者处理有符号的数据,则应该使用“int ”;同时,也应该注意这两种类型都有可能发生溢出的危险;

 

2.循环输入的三种方式

/*循环输入的三种方法*/
/*方法一:利用scanf()的返回值为读取到的字符个数*/
int main()
{
    int i = 0;
    while (scanf("%d", &i) == 1)
    {
        i = pow(i,3);
        printf("%d\n", i);
    }
    return 0;
}
/*方法二:利用EOF*/
int main()
{
    int i = 0;                     //scanf函数读取失败返回的EOF
    while (scanf("%d", &i)!= EOF)  //EOF=end of file(=-1),按ctrl+z结束循环(vs中要按三次)
    {
        i = pow(i, 3);
        printf("%d\n", i);
    }
    return 0;
}
/*方法3:利用~操作符*/
int main()
{
    int i = 0;                       //-1 :10000000000000000000000000000001
    while (~scanf("%d",&i))         //反码:11111111111111111111111111111110
    {                               //补码:11111111111111111111111111111111
        i = pow(i,3);               //~(-1)=0
        printf("%d\n", i);          //如果读取失败,返回EOF(-1),取反变为0,刚好循环结束
    }
    return 0;
}

3.交换两个两个变量值 的三种方法

/*交换两个整数的三种方法以及他们的不足*/
/*方法一 :创建临时变量*/
int main()   方法比较繁琐
{
  int a = 10;
  int b = 20;
  int temp = 0;//临时变量
  //赋值过程
  temp = a;
  a = b;
  b = temp;
  printf("a=%d b=%d", a, b);
  return 0;
}
/*方法二:使用^操作符*/          //不太好想
                                 只针对二进制为改变,不会有溢出的风险
int main()   
{
  int a = 10;
  int b = 20;
  int temp = 0;//临时变量
  //赋值过程
  a = a ^ b;   //理解两个最基本的^操作运算即可
  b = a ^ b;   //1:a ^ a = 0; 自己异或自己=0(因为每一位都相同) 
  a = a ^ b;   //2:0 ^ a = a; 0异或一个数=异或的数(0^1=1 0^0=0)
  printf("a=%d b=%d", a, b);
  return 0;
}
/*方法三*/         /*创建c变量,存储a+b的和,再通过相减,完成赋值*/
                   容易想,但是c有可能发生溢出(超过int 类型的最大值),造成数据丢失
int main()   
{
  int a = 10;
  int b = 20;
  int temp = 0;//临时变量
  //赋值过程
  int c = a + b;
  a = c - a;
  b = c - b;
  printf("a=%d b=%d", a, b);
  return 0;
}

4.改变特定位数0/1

       核心思想:利用&操作符和~操作符(& :一假俱假      ~ :一真俱真)

/*改特定位数的0/1*/
int main()
{
    int a = 13;
    //00000000000000000000000000001101     把第五个0变为1,0^1=1,其他位不变
    //00000000000000000000000000010000
    //00000000000000000000000000011101
    a = a ^ (1 << 4);
    printf("%d\n", a);         //=29
    //把a变回去
    //00000000000000000000000000011101     把第五个1变为0,1&0=0,其他位不变
    //11111111111111111111111111101111     =~(1<<4)
    a = a & (~(1 << 4));
    printf("%d\n", a);
    return 0;                              //理解就好,&一假具假,所以容易出现0,^一真俱真,所以容易出现1
}

5.&&和||的连续操作(与前置,后置结合)

       核心思想:&&只要遇到0(假),后面就不用计算了,就是断路了;同理,||只要遇到1(真),后面也发生断路,不需再计算;

代码如下:

//&  ^关注的二进制位的变化  单目操作符
//&& || 只关注真假  逻辑操作符   计算结果是真,返回1
//&& 一假具假      || 一真俱真
int main()
{
  int a = 1;
  int b = 2;
  int c = 3;     /*a--是先执行&&的操作,再进行a=a-1*/
  int i = a-- && ++b && 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--是先执行&的操作,再进行a=a-1*/
  int i = a++ || ++b || c++;
  printf("%d %d %d", a, b, c);//2 2 3
  return 0;
}

注意:&,^和&&,||根本不是一个东西;前者是单目操作符,进行的是二进制的转换;后者是逻辑操作符,是进行逻辑判断的,只会返回0或1;

目录
相关文章
|
2月前
|
Java
【Java基础面试十一】、int和Integer有什么区别,二者在做==运算时会得到什么结果?
这篇文章解释了Java中`int`基本数据类型和其包装类`Integer`之间的区别,并指出在进行`==`运算时,`Integer`会拆箱为`int`类型,然后比较它们的值是否相等。
【Java基础面试十一】、int和Integer有什么区别,二者在做==运算时会得到什么结果?
|
2月前
|
存储 Java 索引
32 位和 64 位 JVM 中 int 变量的大小解析
【8月更文挑战第21天】
129 0
|
4月前
|
C语言
C语言-----计算两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
C语言-----计算两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同?
|
5月前
|
缓存 安全 Java
Java的Integer和int有什么区别?
Java的Integer和int有什么区别?
46 1
|
5月前
|
SQL 关系型数据库 MySQL
unsigned int 虽然mysql支持,但是不建议使用,因为可能在未来某个版本删除
unsigned int 虽然mysql支持,但是不建议使用,因为可能在未来某个版本删除
40 2
|
5月前
|
存储 编译器 程序员
int 和 long 的区别
int 和 long 的区别
|
5月前
|
编译器 C++
C++_int负数转unsigned
C++_int负数转unsigned
51 0
|
5月前
|
C语言
[C语言][题]两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同。
[C语言][题]两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同。
41 1
|
5月前
|
存储 人工智能 编译器
learn_C_deep_5 (温故知新、sigend char a = -128的深度理解、unsigned int类型的写法规范)
learn_C_deep_5 (温故知新、sigend char a = -128的深度理解、unsigned int类型的写法规范)
|
5月前
|
存储 编译器 程序员
learn_C_deep_4 (类型和变量命名、sizeof(int) *p表示什么意思、原码、反码和补码的概念、计算机中数据计算时,为什么要转为二级制、unsigned和signed关键字)
learn_C_deep_4 (类型和变量命名、sizeof(int) *p表示什么意思、原码、反码和补码的概念、计算机中数据计算时,为什么要转为二级制、unsigned和signed关键字)