C基础-操作符详解

操作符分类:

算数操作符:+ - * / %

//算数操作符
// int main()
// {
//     //   /除法 1.整数除法(除号两端都是整数)  2浮点数除法,除号的两端只要有一个小数就执行小数除法
//     // 除法中,除数为0
//     int a = 7 / 2;
//     printf("%d\n",a); //3
//     double b = 7 / 2;
//     printf("%lf\n",b); //3.000000
//     double c = 7 / 2.0;
//     printf("%lf\n",c); //3.500000
//     int d = 0;
//     int e = 5 / d; //除数不可为0,编译器会报错

//     printf("%d\n",e);

//     return 0;
// }

int main()
{
    int a = 17 % 8; //% 得到数整数的余数
    //int b = 17.0 % 8.0; // %取模操作符的两个操作数必须都是整数才行
    printf("%d\n",a);

    return 0;
}

移位操作符:<< >>

//移位操作符
//  <<左移操作符
//  >>右移操作符
//注意:以为操作符的操作数只能是整数  移动的是二进制
int main()
{
    //int a = 15;//00000000000000000000000000001111 -原码   //00000000000000000000000000001111 -反码 //00000000000000000000000000001111 -补码
    //int c = -15; //10000000000000000000000000001111 -原码 //11111111111111111111111111110000 -反码(原码的符号位不变,其他位按位取反) 11111111111111111111111111110001 -补码(反码+1就是补码)
    //int b = a >> 1;//移动的就是a中的二进制信息 //0000000000000000000000000000111 -  7
    //右移:算术右移(右边丢弃,左边直接补原来的符号位)  逻辑右移(右边丢弃,左边直接补0)
    // C语言没有明确规定是算术右移还是逻辑右移
    //int c = a << 1;//00000000000000000000000000011110
    //整数的二进制表示形式 : 原码 反码 补码 
    //正整数的原码、反码、补码是相同的
    //负的整数原码、反码、补码是要计算的
    //首先不管是正整数还是负整数都可以写出二进制原码  1.根据正负直接写出的二进制序列就是原码
    //1个整型是4个字节 = 32bit位
    //整数在内存中存储的是补码
    //计算的时候也是使用补码计算的
    // printf("%d\n",b); //7
    // printf("%d\n",c); //30

    // int d = -15; //10000000000000000000000000001111
    // int e = d >> 1;//11111111111111111111111111110001  ->  11111111111111111111111111111000 -> 11111111111111111111111111110111   ->00000000000000000000000000001000
    // printf("%d\n",e);

    //!移位操作符不要移负数哦
    int a = 6;// 110
    int b = a << 1;//1100
    printf("%d\n",b); //12

    return 0;
}

位操作符:& | ^

//位操作符
//也是操作二进制位
// &
// int main()
// {
//     int a = 3; //00000000000000000000000000000011
//     int b = -5;//10000000000000000000000000000101  11111111111111111111111111111010 补码11111111111111111111111111111011
//     int c = a & b;
//     // & --  对应二进制位,有0则为0,两个同时为1才是1
//     //00000000000000000000000000000011
//     //11111111111111111111111111111011
//     //00000000000000000000000000000011  -补码

//     printf("%d\n",c); //3

//     return 0;
// }


//|
// int main()
// {
//     int a = 3; //00000000000000000000000000000011
//     int b = -5;//10000000000000000000000000000101  11111111111111111111111111111010 补码11111111111111111111111111111011
//     int c = a | b;
//     // | --  对应二进制位,有1则为1,两个同时为0才是0
//     //00000000000000000000000000000011
//     //11111111111111111111111111111011
//     //11111111111111111111111111111011  -补码
//     //11111111111111111111111111111010
//     //10000000000000000000000000000101 -5
//     printf("%d\n",c); //-5

//     return 0;
// }

//^
int main()
{
    int a = 3; //00000000000000000000000000000011
    int b = -5;//10000000000000000000000000000101  11111111111111111111111111111010 补码11111111111111111111111111111011
    int c = a ^ b;
    // ^ --  对应二进制位,相同为0,相异为1
    //00000000000000000000000000000011
    //11111111111111111111111111111011
    //11111111111111111111111111111000  -补码
    //11111111111111111111111111110111
    //10000000000000000000000000001000
    printf("%d\n",c); //-8

    return 0;
}

//不能创建临时变量,实现两个整数的交换
int main()
{
    int a = 3;
    int b = 5;
    printf("交换前: a=%d b=%d\n",a,b);
    // int tmp = a;
    // a = b;
    // b = tmp;

    // a = a + b;
    // b = a - b;
    // a = a - b;   超过整形最大存储则不行

    //a ^ a -> 0
    //a ^ 0 = a
    // 异或是支持交换律的
    //a ^ b ^ a = 5
    //a ^ a ^ b = 5
    a = a ^ b;
    b = a ^ b; // b = a ^ b ^ b = a
    a = a ^ b;// a = a ^ b ^ a = b
    printf("交换后: a=%d b=%d\n",a,b);


    return 0;
}

编写代码实现:求一个整数存储在内存中的二进制中1的个数

//编写代码实现:求一个整数存储在内存中的二进制中1的个数
//方法1
// int main()
// {
//     //整数有32个bit位
//     //获得32个bit位的每一位,
//     //判断这一位是否为1
//     //是1就是记数器+1
//     int num = 10;
//     int count = 0;

//     while (num)
//     {
//         if (num%2 == 1)
//         {
//             count++;
//         }
//         num = num/2;
        
//     }
//     printf("二进制中1的个数 = %d\n",count);
    
//     return 0;
// }

//方法2
int main()
{
    int num = 10;
    int i = 0;
    int count = 0;
    for(i=0;i<32;i++)
    {
        if (num & (1 << i))
        {
            count++;
        }
    }
    printf("二进制中1的个数 = %d\n",count);
    return 0;
}

赋值操作符: = +=  -=  *= /= ....

//赋值操作符

int main()
{
    int weight = 120;//体重
    weight = 89;  //不满意就赋值
    double salary = 10000.0;
    salary = 20000.0;

    int a = 10;
    int x = 0;
    int y = 20;
    a = x = y+1;//连续复制


    return 0;
}

单目操作符: ! sizeof + -  ~ & *

//单目操作符
// int main()
// {
//     int flag = 5;
//     if(flag == 0)
//     {
//         printf("hehe\n");
//     }
//     if(!flag) //flag为假打印hehe
//     {
//         printf("hehe\n");
//     }
//     if(flag)
//     {
//         printf("haha\n");
//     }

//     return 0;
// }

//单目操作符只有一个操作数
// int main()
// {
//     int a = 5;
//     int b = -a;
//     printf("%d\n",b);

//     return 0;
// }

//& * 应用于指针
// int main()
// {
//     int a = 10;
//     //pa是指针变量
//     int* pa = &a; // &-取地址操作符  取出a的地址
//     *pa = 20;  //解引用操作符(间接访问操作符)-单目操作符-通过pa中存放的地址,找到指向的空间(内容)
//     int c = *pa;
//     printf("%d\n",c);

//     return 0;
// }

//sizeof 不是函数,是操作符号
//sizeof 计算的是类型创建变量的大小,单位是字节
// int main()
// {
//     int a = 10;
//     double b = 10.0;
//     printf("%d\n",sizeof(int));//4
//     printf("%d\n",sizeof(a));//4
//     printf("%d\n",sizeof(b));//8
//     return 0;

// }

// int main()
// {
//     int arr1[10];
//     printf("%d\n",sizeof(arr1)); //40  计算整个数组的大小,单位字节
//     printf("%d\n",sizeof(int [10])); //40
//     int arr2[20];
//     printf("%d\n",sizeof(arr2));//80
    
//     return 0;
// }

// ~ 按位取反   按补码二进制位取反
// int main()
// {
//     int a = 0;
//     printf("%d\n", ~a);
//     //00000000000000000000000000000000
//     //11111111111111111111111111111111  -补码
//     //11111111111111111111111111111110
//     //10000000000000000000000000000001   -1
//     return 0;
// }

// int main()
// {
//     int a = 13;
//     //00000000000000000000000000001101
//     //00000000000000000000000000010000
//     a |= (1<<4);
//     //00000000000000000000000000011101
//     //11111111111111111111111111101111
//     //00000000000000000000000000001101
//     printf("%d\n",a); //29

//     a &= (~(1 << 4));
//     printf("%d\n",a);
//     return 0;
// }

// int main()
// {
//     int a = 0;
//     //scanf  读取失败返回的是EOF
//     //假设scanf读取失败了,返回了EOF ---> -1
//     //while (scanf("%d",&a) != EOF)
//     while(~scanf("%d",&a))  //~ -1为false
//     {
//         printf("%d\n",a);
//     }

//     return 0;
// }

// --前置、后置--
//++前置 、后置++
// int main()
// {
//     int a = 1;
//     int b = a++;  //后置++,先使用,后++
//     //int c = ++a; //先置++ ,先++在使用
//     printf("b=%d a=%d\n",b,a);

//     int c = 1;
//     int e = c--; //后置--,先使用,后--
//     printf("e=%d c=%d\n",e,c);

//     return 0;
// }

//强制类型转换
int main()
{
    int a = (int)3.14;  //强制转换
    printf("%d\n",a);
    // int a = int(3.14) //err

    return 0;
}


void test1(int arr[])   //int*    4/8个字节
{
    printf("%d\n",sizeof(arr));
}
void test2(char  ch[])   //char*    4/8个字节
{
    printf("%d\n",sizeof(ch));
}
int main()
{
    int arr[10] = {0};
    char ch[10] = {0};
    printf("%d\n",sizeof(arr)); //40
    printf("%d\n",sizeof(ch)); // 10
    test1(arr); // x86上是4 ,x64上是8
    test2(ch);  // x86上是4 ,x64上是8


    return 0;
}

关系操作符: > < >= <= =.  !=.    关系操作符只能应用到适合的类型上

int main()
{
    int a = 0;
    int b = 0;
    scanf("%d %d",&a ,&b);
    if(a == 5 && b ==5)
    {
        printf("hehe\n");
    }

    if(a == 5 || b ==5)
    {
        printf("haha\n");
    }

    return 0;
}

int main()
{
    int y = 0;
    scanf("%d",&y);
    //判断是否是闰年   1.能被4整除,并且不能被100整除
    //2 .能被400整除是闰年
    if(((y%4==0) && (y%100!=0)) || (y%400==0))
    {
        printf("y=%d是闰年\n",y);
    }
    else
    {
        printf("不是闰年");
    }

    return 0;
}

逻辑操作符:&& 逻辑与 并且   || 逻辑或 或者

int main()
{
    int i = 0, a = 0, b = 2, c = 3, d =4;
    //i = a++ && ++b && d++;
    //printf("a = %d\n b = %d\n c = %d\n d = %d\n",a,b,c,d);//1 2 3 4
    i = a++ || ++b ||d++;
    printf("a = %d\n b = %d\n c = %d\n d = %d\n",a,b,c,d);//1 3 3 4

    return 0;
}

条件操作符:? :

//条件操作符也叫三目操作符   有三个操作数    exp1 ? exp2 : exp3
//双目操作符   a+b 
//单目操作符 !a

// int main()
// {
//     int a = 0;
//     int b = 0;
//     // if (a > 5)
//     // {
//     //     b = 3;
//     // } else
//     // {
//     //     b = -3;
//     // }

//     //(a > 5) ? (b = 3) : (b = -3);

//     b = (a > 5) ? 3 : -3;
//     printf("%d\n",b);

//     return 0;
// }

int main()
{
    int a = 0;
    int b = 0;
    scanf("%d %d",&a,&b);
    int m = (a > b) ? a : b;
    printf("%d\n",m);

    return 0;
}

逗号表达式 :    ,

//exp1,exp2,exp3,....expN
//逗号表达式 : 从左向右计算,整个表达式的结果是最后一个表达式的结果
// int main()
// {
//     int a = 1;
//     int b = 2;
//     int c = (a>b, a = b+10 ,a,b=a+1); //13
//     printf("%d\n",a); //12
//     printf("%d\n",b); //13
//     printf("%d\n",c); //13
//     return 0;
// }

// int main()
// {
//     // a = get_val();
//     // count_val(a);

//     // while (a > 0)
//     // {
//     //     //业务处理
//     //     a = get_val();
//     //     count_val(a);
//     // }

//     //使用逗号表达式
//     while (a = get_val(),count_val(a), a>0)
//     {
//         //业务处理
//     }
    


//     return 0;
// }

下标引用,函数调用和结构成员:  []. ().  .  ->  

[] 下标引用操作符

操作数:一个数组名+一个索引值

//[] 下标引用操作符
// int main()
// {
//     int arr[10] = {1,2,3,4};
//     //数组的起始是有下标的,下标是从0开始的
//     printf("%d\n",arr[2]); //arr 和 2是[]的两个操作数


//     return 0;
// }

()函数调用操作符

接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数

//     return 0;
// }

int Add(int x,int y)
{
    return x + y;
}
//函数调用操作符
int main()
{
    int len = strlen("abc"); //()函数调用操作符
    //()的操作数是:strlen 函数名   "abc" 实参
    printf("%d\n",len);

    int c = Add(3,5);
    printf("%d\n",c);
    //对于函数调用操作符来说,最少有1个操作数

    return 0;
}

访问一个结构的成员

. 结构体,成员名

-> 结构体指针 -> 成员名

结构体 -复杂类型  -自定义类型

//可变参数列表 -参数的个数是变化的 -探索
struct Book
{
    char name[30];
    char author[20];
    float price;
};

void Print(struct Book * p)
{
    //printf("%s %s %f\n",(*p).name,(*p).author,(*p).price);
    printf("%s %s %f\n",p->name,p->author,p->price);
    // ->   
    //结构指针->成员名   p->name
}

int main()
{
    struct Book b1 = {"C语言","ccc",66.8f};//书
    struct Book b2 = {"Java入门","jjj",55.8f}; //书
    Print(&b1);
    //printf("%s %s %f\n",b1.name,b1.author,b1.price);
    //printf("%s %s %.1f\n",b2.name,b2.author,b2.price);
    //结构体变量,成员名

    return 0;
    
}

表达式求值

表达式求值的顺序一部分是由操作符的优先级和结核性决定。

同样,有些表达式的操作数在求值的过程中困难需要转化为其他类型

//表达式求值
//1表达式在计算的过程中,有哪些类型转换?
//2表达式的求值顺序是怎么样的
//类型转换   1整型提升   2算术转换 
//整形提升 C的整型算术运算总是至少一缺省整型类型的精度来进行的  为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升

int main()
{
    char c1 = 5;
    //00000000000000000000000000000101
    //00000101 - c1
    char c2 = 127;
    //00000000000000000000000001111111
    char c3 = c1 + c2;  // -124
    //00000000000000000000000000000101
    //00000000000000000000000001111111
    //00000000000000000000000010000100

    //%d - 10进制的形式打印有符号的整数
    //11111111111111111111111110000100
    //10000000000000000000000001111100    -124
    printf("%d\n",c3);

    return 0;
}

// %u 打印10进制的形式无符号的整数
// int main()
// {
//     char c = 1;
//     printf("%u\n",sizeof(c)); //1
//     printf("%u\n",sizeof(+c)); //1
//     printf("%u\n",sizeof(-c)); //1


//     return 0;
// }

// int main()
// {
//     float f = 3.14;
//     int a = 10;
    
//     char b = a + f; // 13
//     int c = a + f; // 13

//     printf("%d\n",b);
//     printf("%d\n",c);


//     return 0;
// }

//相邻操作符优先级高的先算,低低后算
//相邻操作符的优先级相同的情况下,结合性起作业
// int main()
// {
//     int a = 2 + 3 * 5;

//     return 0;
// }

// int main()
// {
//     int i = 10;
//     i = i-- - --i * (i = -3) * i++ + ++i;
//     printf("i = %d\n", i);

//     return 0;
// }

int fun()
{
    static int count = 1;
    return ++count;
}

int main()
{
    int answer;
    answer = fun() - fun() * fun(); //  2 - 3*4    -10
    printf("%d\n",answer); //输出多少

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值