操作符,原码、反码、补码之间的关联,隐式类型转换:整型提升和算术转换

     >>——移位操作符中的右移操作符——移动的是二进制位
右移操作符有两种移位方式

1、算术右移
右边丢弃,左边补符号位。即原来二进制首位补0或1。数为正数则补0,为负数则补1.
2、逻辑右移
右边丢弃,左边补0。

原码,反码,补码。
内存中存的是补码,输出结果为原码。原码取反为反码(不改变符号位),反码加1为补码。

左移操作符——<<——左边丢弃一位,右边加0
注意,不要移位负数,且只能作用于整形。eg:<<-1//erro


int main()
{
    int a = 16;
    int b = a >> 3;//右移三位,结果为2
    printf("%d", b);
    return 0;
}

位操作符
&——按(二进制)位与——有0则0
|——按(二进制)位或——有1则1
^——按(二进制)位异或——不同则1,相同为0

补:对于两个数的每个二进制位都进行比较后,输出一个新的二进制序列

不用临时变量,进行两个数的交换
int main()
{
    int a = 5;
    int b = 10;
    //(1)加减法——缺陷:可能会造成内存溢出的情况。不适用于数较大的情况。
    /*a = a + b;
    b = a-b;
    a = a - b;*/
    //异或法
    a = a ^ b;//此时a可以将其认为是密码
    b = a ^ b;//密码与10异或,得到的是另一个数,即5
    a = a ^ b;//同上
    printf("a=%d\nb=%d\n", a, b);
    return 0;
}

编写一个代码,求一个整数存储在内存中的二进制中1的个数
int main()
{
    int num = 0;
    int i = 0;
    int count = 0;
    scanf("%d", &num);
    for(i;i<32;i++)
    {
        if (1 == ((num >> i) & 1))//num每次向右移动1位并且与1。若输出1,则原数中必为1
        {
            count++;
        }
    }
    printf("%d", count);
    return 0;
}

复合赋值符:+=,-=,*=,/=,%=,>>=,<<=,&=,|=,^=
eg:a+=1——a=a+1

单目操作符:!——取反——常与if语句连用,用来表示条件为假时的操作

关于sizeof需要注意的细节
int main()
{
    short s = 0;
    int a = 10;
    printf("%d\n", sizeof(s = a + 5));//2        sizeof里的算式不参与实际运算
    printf("%d\n", s);//0
    return 0;
}

~——按(二进制)位取反
~的一种适用情况:

int main()
{
    int a = 11;//二进制为:1011
    //将进制位第三位改为1
    a = a | (1 << 2);//0100|1011=1111
    printf("%d\n", a);
    //将第三位进制位改回0
    a = a & (~(1 << 2));//1<<2——00...0100,~——11....1011,&1111——1011
    printf("%d\n", a);
    return 0;
}

++a——前置++。先++,后使用
a++——后置++。先使用后++

int main()
{
    int a = 10;
    printf("%d\n",++a);//11
    printf("%d\n", a);//11
    int b = 10;
    printf("%d\n", b++);//10
    printf("%d\n", b);//11
    return 0;
}

(类型)——强制类型转换
eg:
int main()
{
    int a =(int)3.14;
    return 0;
}

逻辑操作符
注意区分逻辑与(&&)和按位与(&),区分逻辑或(||)和按位或(|)
逻辑与和逻辑或是对其数字本身进行的一种比较。逻辑与:两者都为真才为真,逻辑或:两者中其中一种为真,则为真。

int main()
{
    //int i = 0, a = 0, b = 2, c = 3, d = 4;
    //i = a++&&++b&&d++;//先判断真假后进行加加操作。对于逻辑与,如果左边为假,则逻辑确定为假,后面不再计算
    //printf("%d %d %d %d", a, b, c, d);//结果为1,2,3,4
    int i = 0, a = 1, b = 2, c = 3, d = 4;
    i = a++||++b||d++;//对于逻辑或,如果左边为真,则逻辑确定为真,后面不再计算(确定为计算机偷懒!!!)
    printf("%d %d %d %d", a, b, c, d);//结果为2,2,3,4
    return 0;
}

条件操作符(又称三目操作符)
exp1?exp2:exp3    ——判断表达式1,如果表达式1为真,则执行表达式2,否则执行表达式3
eg:int max = (a > b ? a : b);

逗号表达式
就是用逗号隔开的多个表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果
exp1,exp2,exp3
eg:int c=(a>b,a=b+10,a,b=a+1);

[]——下标引用操作符
操作数:一个数组名+索引值——索引值:即[]里面的值

()——函数调用操作符:接受一个或者多个操作数。第一个操作数是数组名,剩余的操作数就是传递给函数的参数。

.(点)操作符——用法:变量名.成员名               ->操作符——用法:结构体指针->成员名
eg:
//首先创建一个结构体
struct stu               //类型名:struct stu
{
    int age;
    char id[20];                       //这上面的定义相当于图纸,并不占用内存空间
    char name[20];
};
int main()
{
    // 创建hz变量并对其初始化相当于一个建房子的过程,初始化完成相当于房子完工占用地皮。即初始化完成后将占用内存。
    struct stu hz = { 20,"2009010125","张三" };//创建一个变量名为hz的一个变量,并对其进行初始化。
    printf("%d\n", hz.age);
    printf("%s\n", hz.id);
    printf("%s\n", hz.name);
    struct stu* p = &hz;//hz作为一个变量,在内存中一定有地址。对其取地址然后赋给指针变量p。
    printf("%d\n", (*p).age);
    printf("%d\n", p->age);
    return 0;
}

/*表达式求值
表达式的求值的顺序一部分是由操作符的优先级和结合性决定。同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。
隐式类型转换
1、整形提升:c的整形算术运算总是至少以缺省整形类型的精度来进行的,为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为
普通整形(4个字节)。
用法:字节数小于整形的非整形(例如char,short)类型的变量在进行求值时,首先会将其的二进制位转换为整形(符号位为1填1,为0填0),计算完成后进行得到的
结果若仍然为小于整形的变量,则需要将该二进制进行截断后,将其转换成原码,再进行读取。
2、算术转换:如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数类型,否则操作无法进行
用法:字节数小的类型与更大的类型进行求值时,会将小的类型转换成大的类型再进行运算。

若表达式有歧义,或者计算路径不唯一,则称该表达式为错误表达式
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值