C语言 -- 操作符详解

【C语言】

操作符https://mp.csdn.net/editor/html/115218055

数据类型https://mp.csdn.net/editor/html/115219664

自定义类型:结构体、枚举、联合https://mp.csdn.net/editor/html/115373785

变量、常量https://mp.csdn.net/editor/html/115230188

分支、循环语句https://mp.csdn.net/editor/html/115234118

字符串+转义字符+注释https://mp.csdn.net/editor/html/115231391

指针https://mp.csdn.net/editor/html/115281303

数组https://mp.csdn.net/editor/html/115266750

函数https://mp.csdn.net/editor/html/115265396

 

内容来自   B站  C语言教学视频   https://www.bilibili.com/video/BV1RX4y1u7Zh

 

 

 

操作符

1.算数操作符(加、’减、乘、除、取模):     +   -   *   /   %

2.移位操作符(右移、左移):   >>    <<

3.位操作符(与、或、异或):   &    |     ^       &  按位与       |  按位或       ^  按位异或  (注:他们的操作数必须是整数。)

4.赋值操作符: =复合赋值符(方便书写):    +=   -=   *=   /=   %=  >>=   <<=  &=   |=   ^=

5.单目操作符:

6.关系操作符

7.逻辑操作符

8.条件操作符

9.逗号表达式

10.下标引用、函数调用和结构成员

11.表达式求值  


 

1.算数操作符(加、’减、乘、除、取模):     +   -   *   /   %

#include <stdio.h>
     int main ()
     {
         int a = 5 / 2; //商2余1  除 取商
         int b = 5 % 2; //        模 取余数
         double c = 5 / 2.0;//浮点类型  除法如果想得到小数,至少除数或被除数至少一个为浮点数
         double d = 5 % 2.0;//error
         printf("a = d%", a);// a=2
         printf("b = d%", b);// b=1
         printf("c = lf%", c);// c=2.50000 默认后面打印6位小数
         return 0;
     }

小结:
     1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
     2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
     3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

 

2.移位操作符(右移、左移):   >>    <<

#include <stdio.h>
 int main ()
 {   
     int a = 16;// 整形,4个字节,32位,最高位(最左边)为符号位 0为正 1为负
     int b = 5
     //  >>  右移操作符
     //移动的是二进制位
     //整数的2进制表示有:原码、反码、补码
     //储存到内存的是补码(重点注意)
     //  10000000000000000000000000000001   -1   原码
     //  11111111111111111111111111111110   -1   反码    
     //  11111111111111111111111111111111   -1   补码
     //  00000000000000000000000000010000    16     a       
     //  00000000000000000000000000001000    8   a >> 1   右移1位有除2的效果
     //  00000000000000000000000000000101    5      b
     //  00000000000000000000000000001010    10   b << 1
     int A = a >> 1;
     int B = b << 1;
     printf("%d", A); //8
     printf("%d", B);//10
     return 0;
 }


 右移操作符 移位规则(2种):1. 算术移位 左边用原该值的符号位填充,右边丢弃(通常采用方式)   2. 逻辑移位 左边用0填充,右边丢弃    
 左移操作符 移位规则:左边抛弃、右边补0   
 警告: 对于移位运算符,不要移动负数位(如-1),这个是标准未定义的。 
 例如:位操作符
    int num = 10;
    num>>-1;  // 移动 -1 位,错误

     

3.位操作符(与、或、异或):   &    |     ^
       &  按位与
       |  按位或
       ^  按位异或
  (注:他们的操作数必须是整数。)

 #include <stdio.h>
  int main ()
   {   
     
     int a = 3;
     int b = 5;
     int c = a&b;  //  & 按2进制位与
     int d = a|b;  //  | 按2进制位或
     int e = a^b;  //  ^ 按2进制位异或,相同为0,相异为1   
     //  00000000000000000000000000000011    3   a
     //  00000000000000000000000000000101    5   b 
     
     //  00000000000000000000000000000001    1   a&b
     //  00000000000000000000000000000111    7   a|b
     //  00000000000000000000000000000110    6   a^b
     printf("%d", c);//1
     printf("%d", d);//7
     printf("%d", e);//6
     return 0;
 }

 

4.赋值操作符: =
复合赋值符(方便书写):    +=   -=   *=   /=   %=  >>=   <<=  &=   |=   ^=

// a = a +1;
// a += 1;
// 其它复合运算符类似

 

5.单目操作符:

!           逻辑反操作
-           负值
+           正值
&           取地址
sizeof       操作数的类型长度(以字节为单位)
~           对一个数的二进制按位取反
--           前置、后置 --
++           前置、后置 ++
*           间接访问操作符 ( 解引用操作符 )
( 类型 )       强制类型转换
 
      #include <stdio.h>
      int main()
      {
           int a = 1;
           int* p = &a;//取地址操作符
           int arr[10] = {0};
           *p = 2; //解引用操作符
           
           printf("d% d%\n", a, p);// 2 2
      
           //sizeof 计算的变量(类型)所占空间的大小,单位是字节 
           printf("%d\n", sizeof a );//4    
           printf("%d\n", sizeof int);//error 不能这么写
           printf("%d\n", sizeof(int));//4
           
           printf("%d\n", sizeof(arr));//40    4(整型大小)*10(元素)
           printf("%d\n", sizeof(int [10]));//40  int [10]是arr的类型
           return 0; 
       }
  #include <stdio.h>
  int main()
  {  
    int a = 10;
    a = 20;// = 赋值    ==判断相等
    a += 20;// 相等于a = a+20  
    // 赋值运算符 += -= *= /= %= &= |= ^= <<= >>=
    //C语言中表示真假  0-假 非0-真   !逻辑反操作符判断真假
    printf("%d", !a);//打印结果为0
    return 0;
  }
  #include <stdio.h>
  int main()
  { 
    int arr[10] = {0};//10个整型元素的数组
    int sz = 0;
    // 10*sizeof(int) = 40; //数组总大小
    int a = 10;
    //sizeof计算变量名或者类型所占空间大小,单位字节
    printf("%d\n", sizeof(a));//打印结果为4  计算变量名a大小
    printf("%d\n", sizeof(int));//4 计算int类型大小
    printf("%d\n", sizeof a);//4 计算变量名括号可以省略
    // printf("%d\n", sizeof int);// error 计算类型不能省略括号
    printf("%d\n", sizeof(arr));//40  计算数组总的大小 
    sz = sizeof(arr)/sizeof(arr[0])  //数组元素个数 = 数组总大小/每个元素的大小
    printf("%d\n", sz); //10 计算数组元素个数
    return 0;
  }

前置、后置--    前置、后置++

  前置/后置 自增/自减
  #include <stdio.h>
  int maain()
  { 
    int a = 10;
    int b = 20;
    int c = a++;//后置++  先使用,再++
    int d = ++b;//前置++  先++,再使用
    printf("a = %d b = %d c = %d d = %d\n", a, b, c, d);//a=11 b=21 c=10 d=21
    //前置--  后置--   类似
    return 0;
  }

强制类型转换

  强制类型转换 (一般情况下不建议在代码中写强制类型转换)
  #include <stdio.h>
  int main()
  { 
   int a = 3.14;//这样写会有警告提示
   int b = (int)3.12;//double 转换 int
    return 0;
  }

sizeof 注意事项

#include <stdio.h>
int main()
{
    short s = 0;
    int a = 10;
    printf("%d\n", sizeof(s = a + 5)); // 2  sizeof()在这计算的是short短整型的大小2字节
    printf("%d\n", s);//0  sizeof() 括号内部表达式不参与运算
    return 0;
}
#include <stdio.h>
void test1(int arr[])
{
 printf("%d\n", sizeof(arr));//(2)  4  指针4(32平台)/8(64平台)
}
void test2(char ch[])
{
 printf("%d\n", sizeof(ch));//(4)  4  指针
}
int main()
{
 int arr[10] = {0};
 char ch[10] = {0};
 printf("%d\n", sizeof(arr));//(1)  40
 printf("%d\n", sizeof(ch));//(3)   10
 test1(arr);
 test2(ch);
 return 0; }
问:
(1)、(2)两个地方分别输出多少?
(3)、(4)两个地方分别输出多少?

~ 按位取反

#include <stdio.h>
      int main()
      {    
           int a = 0;
           // ~ 按2进制位取反    0、正数,原码补码反码相同,数据放在内存中都是补码
           // 00000000000000000000000000000000  a    0     
           // 11111111111111111111111111111111  ~a   0按位取反后的结果  此时储存在内存  为补码 如需打印则需要原码 
           // 11111111111111111111111111111110       此时需取反  反码 
           // 10000000000000000000000000000001       再变为     原码  再打印出
           printf("%d\n", ~a);//-1
           return 0; 
       }

6.关系操作符

>
>=
<
<=
!=   用于测试 不相等
==       用于测试 相等
警告: 在编程的过程中 == = 不小心写错,导致的错误。
 
 
 
 

7.逻辑操作符

&&     逻辑与

||          逻辑或
  逻辑操作符  &&与(同真则真)  ||或(一真为真)
  #include <stdio.h>
  int main()
  {
    int a = 0;
    int b = 5;
    int c = a&&b;
    int d = a||b;
    //   &&  || 判断真假,假0,真非零
    printf("c = %d d = %d\n", c, d);//c=0 d=1  输出时用 1表示真  0表示假
    return 0;
  }
360笔试题:
#include <stdio.h>
int main()
{
    int i = 0, a = 0, b = 2, c = 3, d = 4;
    i = a++ && ++b && d++;   //  逻辑与 && 的特点  左边为假,右边就不进行计算,a++ 后增前为0,假,所以b,d都不运算
    printf("a = %d\n b = %d\n c = %d\n d = %d\n i = %d", a, b, c, d, i); //1 2 3 4 0
    //i = a++||++b||d++;  //逻辑或 || 的特点  左边为真,右边就不进行运算
    //printf("a = %d\n b = %d\n c = %d\n d = %d\n i = %d", a, b, c, d,i); // 1 3 3 4 1
    return 0;
}

区分逻辑与和按位与 区分逻辑或和按位或

1&2----->0 
1&&2---->1
 
1|2----->3 
1||2---->1

8.条件操作符

exp1 ? exp2 : exp3

条件操作符    表达式1 ?表达式2 :表达式3;
#include <stdio.h>
int main()
{
    int a = 10;
    int b = 20;
    int max1 = 0;
    int max2 = 0;
    max1 = (a > b ? a : b);  //相当于  if(a>b) max1=a; else max1=b;
    max2 = (b > a ? b : a);
    printf("max1 = %d max2 = %d\n", max1, max2);//max1=20 max2=20
    return 0;
}

 

9.逗号表达式

逗号表达式,就是用逗号隔开的多个表达式。 逗号表达式,从左向右依次执行。整个表达式的结果是最
后一个表达式的结果。
 
#include <stdio.h>
int main()
{
    int a = 1;
    int b = 2;
    int c = (a > b, a = b + 10, a, b = a + 1);
    printf("%d", c); // 13
    return 0;
}

使代码更简便


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

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

 

10.下标引用、函数调用和结构成员

10.1  [ ] 下标引用操作符
操作数:一个数组名 + 一个索引值
 
int arr[10];//创建数组
 arr[9] = 10;//实用下标引用操作符。
 [ ]的两个操作数是arr和9。

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

#include <stdio.h>
int get_max(int x, int y)
{
    return (x > y ? x : y);
}
int main()
{
    int a = 1;
    int b = 2;
    int max = get_max(a, b); //函数调用的时候 () 就是函数调用操作符
    printf("%d", max); // 2
    return 0;
}

10.3访问一个结构的成员

.     结构体.成员名
->     结构体指针->成员名
#include <stdio.h>
//创建一个结构体类型  struct Stu
struct Stu
{
    //成员变量
    char name[20];
    int age;
    char id[20];
};
int main()
{
    int a = 10;
    //使用struct Stu 这个类型创建了一个学生对象 s1
    struct Stu s1 = { "张三", 20, "20170102" };
    struct Stu* ps = &s1;
    // 结构体指针->成员名
    printf("%s\n", ps->name); //张三
    printf("%s\n", (*ps).name);//张三
    //   结构体变量.成员
    printf("%s\n", s1.name);//张三
    printf("%d\n", s1.age); //20
    printf("%s\n", s1.id);  //20170102

    return 0;
}

 

11.表达式求值  

11.1整形提升    (p71视频)

C 的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为 整型
提升
 
整型提升的意义
表达式的整型运算要在 CPU 的相应运算器件内执行, CPU 内整型运算器 (ALU) 的操作数的字节长度
一般就是 int 的字节长度,同时也是 CPU 的通用寄存器的长度。
因此,即使两个 char 类型的相加,在 CPU 执行时实际上也要先转换为 CPU 内整型操作数的标准长
度。
通用 CPU general-purpose CPU )是难以直接实现两个 8 比特字节直接相加运算(虽然机器指令
中可能有这种字节相加指令)。所以,表达式中各种长度可能小于 int 长度的整型值,都必须先转
换为 int unsigned int ,然后才能送入 CPU 去执行运算
 
如何进行整体提升呢?
整形提升是按照变量的数据类型的符号位来提升的
 
//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111


//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
//无符号整形提升,高位补0

11.2算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类
型,否则操作就无法进行。下面的层次体系称为 寻常算术转换
long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运
算。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值