C语言 day2 | 我的日常分享

C语言 day2

类型转换

1. 自动类型转换

字节数小的向字节数大的转换
图片

  • 案例1:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include<stdio.h>
    int main(int argc,char *argv[]){
    int num1 = -20;
    unsigned int num2= 10;
    if(num1 + num2 >0){
    printf(">0;num1+num2=%d\n",num1+num2);
    }else{
    printf("<0;num1+num2=%d\n",num1+num2);
    }

    return 0;
    }

    运行结果: >0;num1+num2=-10
    图片
    原因:是因为无符号整型加有符号整型会自动转化为无符号整型,然而-20的补码是个很大的数,加上10必然大于0,所以结果是大于零的;但为什么num1+num2=-10呢?因为输出时,系统是将其当成有符号数输出的

  • 案例2:intdouble

    1
    2
    3
    4
    5
    6
    7
    #include<stdio.h>
    int main(int argc,char *argv[]){
    int num = 10;
    printf("%d\n",sizeof(num+3.14f));
    printf("%d\n",sizeof(num+3.14));
    return 0;
    }

    运行结果:
    4 8
    图片

  • 案例3: char和short类型转换
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include<stdio.h>
    int main(int argc,char *argv[]){
    char ch = 'a';
    short num = 10;
    printf("%d\n",sizeof(ch));
    printf("%d\n",sizeof(num));
    printf("%d\n",sizeof(ch + ch));
    printf("%d\n",sizeof(num + num));
    printf("%d\n",sizeof(ch + num));
    return 0;
    }
    运行结果:
    1 1 4 4 4
    图片
    原因:charshort自身字节数过小,只有一个字节,只要0到255的范围,很容易溢出,超过255就溢出了,所以系统为了防止溢出,只要char 和 short类型参加运算,系统会将自身类型转化成int

2. 强制类型转换

(类型说明符)(表达式)

  • 案例3: char和short类型转换
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include<stdio.h>
    int main(int argc,char *argv[]){
    float x = 3.14f;
    int j = 0;
    // j=x;
    j=(int)(x);
    printf("j=%d\n",j);
    printf("x=%f\n",x);
    return 0;
    }
    运行结果:
    j=3 x=3.140000
    图片

无论强制类型转换,还是自动类型转换,都是进行临时的转换,不会改变原来数据的类型

运算符

练习:键盘输入一个数,取出每位上的数值

1.位运算符

  • &:按位与 全1为1 其他为0
        1010 1010
    & 1111 0000
    ······························
        1010 0000
    特点:和1相与 保持不变 和0相与清0
    应用场景:将固定位清0

    第几位是从右往左看的,从第0位开始

  • |:按位或 有1为1 全0为0
        1010 1010
    & 1111 0000
    ······························
        1111 1010
    特点:和1相或 值为1 和0相或 保持不变
    应用场景:将固定位置1

  • ~:按位取反 1变0 0变1
    ~1010 1010 == 0101 0101
    应用场景:配合按位与、按位或使用

  • ^:按位异或 相同为0 不同为1
        1010 1010
    & 1111 0000
    ······························
        0101 1010
    特点:与0异或 保持不变;与1异或 取反
    应用场景:将固定位发生高低电频翻转

  • <<左移
    左移,低位补0
    例如:1010 0110<<21001 1000

  • >>右移
    逻辑右移:低位右移,高位补0
    算术右移:

    1. 无符号数: 低位右移,高位补0
    2. 有符号数: 低位右移,高位补符号位

逻辑右移还是算术右移是由编译器决定的

综合案例:
C语言中是不能直接表示二进制的,我们可以用十六进制来进行表示二进制四位和正好为十五,所以用十六进制表示很方便

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
unsigned char data = 0xaa;//1010 1010
//1*2^3+0*2^2+1*2^1+0*2^0=8+0+2+0=10;10在十六进制中即为a 故为0xaa

//将data的第1、5位清0
data = data & 1101 1101;
/*
1101 1101=~(0010 0010)=~(0010 0000|0000 0010)=~(0000 0001<<5|0000 0001<<1)=~(0x01<<5|0x01<<1)
*/
data = data & ~(0x01<<5|0x01<<1);

//将data的第3、4位 置1
data = data | 0001 1000;
/*
0001 1000 = 0001 0000|0000 1000=0x01<<4|0x01<<3
*/
data = data | 0x01<<4|0x01<<3;

以后一般都是这样操作的,将第m、n位清0~(0x01<<m|0x01<<n) 将第m、n位置1(0x01<<m|0x01<<n)

  • ,逗号运算符 取最后一个逗号的数
    案例1:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include<stdio.h>
    int main(int argc,char *argv[]){
    int num1=0;
    int num2=0;
    num1 = 3,4,5,6;
    num2 = (3,4,5,6);
    printf("num1=%d",num1);
    printf("num2=%d",num2);
    return 0;
    }

    运行结果:num1=3 num2=6

  • 自增自减++ --
    ++i 先加后使用
    i++ 先使用后加

    如果单独使用就没什么区别

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include<stdio.h>
    int main(int argc,char *argv[]){
    int a=0,i=0;
    a=i++;
    /*即a=i;
    i=i+1;*/

    /*a=++i;
    即i=i+1;*/
    a=i;

    return 0;
    }