C语言要点摘录(11~14)

本文深入探讨了C语言中的各种运算符,包括逻辑运算符、位运算符、自增自减运算符及其特殊行为,以及优先级和类型转换规则。通过具体示例解释了运算符的工作原理,并提供了关于如何避免常见陷阱的建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

十一.逻辑运算符使用分析

           &&和||的短路规则:||从左向右计算,遇到为真的条件时停止计算,整个表达式为真;所有条件为假时,表达式才为假

                                              &&从左向右计算,当遇到为假的条件时停止计算,整个表达式为假;所有条件为真时表达式才为真。

           !运算符的结果只有0和1,只有作用0时才为1,作用不为零时结果是0.

            三目运算符(a?b:c)可以作为逻辑运算符的载体。


十二.位运算符:&,|,^,~,<<,>>

         位运算符优先级比数学运算符优先级别低,所以同时参与运算的时候,尽量使用括号来表达计算次序:

     例如:0x1<<2+3,运算的结果就是0x1<<(2+3),不是我们想要的结果,应该这样写:(0x1<<2)+3

        异或^运算符可以用来交换两个变量,利用两个相同变量异或为0,变量和0异或等于他自己本身的规则


十三.++,--操作符

        

int i = 3;
(++i) + (++i) + (++i) = ?

     结果有两个16或者18,编译器有两个解析方式,第一个是认为括号里面的优先级最高所以先把括号里面的运算完成,结果i=6.

然后6+6+6=18,另一种是先计算前两个括号相加,i经过两次++,=5所以最后结果是5+5+6=16,例如gcc,g++。

     这是和编译器的方式有关系的,尽量不要这样写代码

使用逗号运算符,可以使++运算符按照顺序来,不会被编译器优化掉

int x;
int i = 3;
x = (++i,i++,i+10);

     编译器的贪心法读取:编译器处理的每个字符应该尽可能多的包含字符

                                             编译器以从左到右的顺序一个一个尽可能多的读入字符

                                             当读入的字符不可能和已读入的字符组成合法符号为止

int i=0;int j = ++i+++i+++i;====》++i++ + i++ +i,所以编译器会报错,因为++0++是错误的

b = b/*p  ,因为编译器解析成为:b = b /*p,/*后面解析成为注释,加上空格就可以正确,b=b / *p

a+++b ====> a++  + b合法

结束贪心法的方法:使用空格或者分号可以告诉编译器不要贪心,所以多使用空格有好处

       

十四.    优先级和类型转换符

       

        容易出错的优先级:

                                     

#include <stdio.h>
#include <malloc.h>

typedef struct _demo
{
    int* pInt;
    float f;
} Demo;

int func(int v, int m)
{
    return (v & m != 0);
}

int main()
{   
    Demo* pD = (Demo*)malloc(sizeof(Demo));
    int *p[5];
    int *f();
    int i = 0;
    
    i = 1, 2;
    
    *pD.f = 0;
    
    free(pD);
    
    return 0;
}

编译会报错。解析:根据优先级表,int *p[5],int *f(),i=1,2都不能得到我们想要的结果,这样的写法能够看得清晰很多:int* p[5],int* f().(注:要利用好空格)。编译器报错会在*pD.f = 0;因为编译器会解析成为*(pD.f)

C语言隐式类型转换:

     

#include <stdio.h>

int main()
{
 char c = 'c';
 short s = 0;

 s= c;

printf("%d\n",sizeof(s+c));
}

打印结果:4

解析:char和short相加,隐式转换成为int,4个字节(char是一个字节,short是两个字节)

     


    

#include <stdio.h>

int main()
{
    int i = -2;
    unsigned int j = 1;
    
    if( (i + j) >= 0 )
    {
        printf("i+j>=0\n");
    }
    else
    {
        printf("i+j<0\n");
    }
    
    printf("i+j=%d\n", i + j);
    
    return 0;
}

打印结果:i+j>0,i+j=-1;

  解析:因为int型的i和unsigned int型的j相加,类型自动升级为unsigned int,所以i+j=-1转成整型数就是0xffffffff,所以肯定大于0,最后printf打印的时候,使用的是

%d格式,这是一个int型的格式,所以可以正常打印-1,如果使用%ud就会打印出很大的整数,使用%x就会打印十六进制数0xffffffff



                                          

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值