2021.12.12 史上最全操作符详解

目录

 算数操作符

 移位操作符 

 位操作符 

 赋值操作符

 单目操作符 

 关系操作符

 逻辑操作符

 条件操作符(三目操作符) 

 逗号表达式 

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

 结构成员访问操作符


算数操作符

   +   -   *   /   %

加号、减号、乘号、除号 均为我们所常见的符号。

对于 / 操作符,如果两个操作数中有一个为浮点数,则执行浮点数除法。

%(取模操作符)举例:5 / 2 = 2····1  商为 2,余数为 1,则 5%2的值便为1。

注意:%操作符的两个操作数都需为整数。

示例:

2021.12.12 史上最全操作符详解_第1张图片


移位操作符 

右操作符 >>

注意:右移操作符分为两种情况

a:算数右移(右边丢弃,左边补原符号位)

b:逻辑右移(右边丢弃,左边补0)

举例:(我们右移负数 -1)(我们来尝试了解vs编译器为那种右移方法)

负数在内存中储存的为补码   正数的 原码 反码 补码 相等

   (直接根据数值写出的二进制序列为原码)  (二进制的最左边为符号位,为1则负,为0则正)

(-1)二进制原码: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 

                            (原码的符号位不变,其他位对照取反为反码)

(-1)二进制反码: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0

                             (在反码的基础上加1,就为补码)

(-1)二进制补码: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
    int a = -1;
    int b= a >> 1 ;
  // 算数右移   1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1          
 //            1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1
 // 逻辑右移    0  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1        
    printf("%d", b);
    return 0;
}

输出结果为: 

2021.12.12 史上最全操作符详解_第2张图片

由此可见我们vs编译器进行的是算数右移。


左操作符 <<

(把 整数 的二进制位向左移动一位)(规则:左边抛弃,右边补0)

举例 :

2021.12.12 史上最全操作符详解_第3张图片


位操作符 

&  按 位 与   (两数二进制一一对应,0为假,1为真,有假为假,两个都为真则为真) 

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
    int a = 3 ;
    int b = 5 ;
    int c = a & b;
    // a的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
    // b的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
    // c的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
    printf("%d", c);
    return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第4张图片


|  按 位 或 (两数二进制一一对应,0为假,1为真,有真为真,两个都为假则为假)

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
    int a = 3 ;
    int b = 5 ;
    int c = a | b;
    // a的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
    // b的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
    // c的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1  1
    printf("%d", c);
    return 0;
}

结果为: 

2021.12.12 史上最全操作符详解_第5张图片


^  按 位 异 或     (两数二进制一一对应,两数相同为0,两数不同1)

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
    int a = 3 ;
    int b = 5 ;
    int c = a ^ b;
    // a的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
    // b的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1
    // c的二进制 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1  1 0
    printf("%d", c);
    return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第6张图片


 赋值操作符

= ) 为赋值     (==)为判断相等     我们要注意区分开来 

复合赋值符:  +=    -=    *=    /=    >>=    <<=    %=   &=   ^=   |=

举例: 

2021.12.12 史上最全操作符详解_第7张图片


单目操作符 

 !  逻辑反操作

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
	int flag = 5;
	printf("!flag=%d\n", !flag);
	if (flag)
	{
		printf("he\n");
	}
	//本来flag =5 ,不为0,为真,  ! flag 逻辑取反,则 ! flag 为假
	if (!flag)
	{
		printf("yeah\n");
	}
	
	return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第8张图片


-  负值   +  正值   & 取地址     (十分常见)

举例:( scanf 的基本格式)

int a=0;

scanf("%d", &a);


sizeof  (计算变量、数组、类型的大小—单位是字节—操作符)

举例1:

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
 
int main()
{
	char arr4[] = "abcdef";
	               //    "abcdef\0"
	printf("%d\n", sizeof (arr4) );
	return 0;
}

打印结果为:

2021.12.12 史上最全操作符详解_第9张图片

sizeof (“a b c d e f \0”)一共七个元素—— 7*1=7

举例2:(int 类型的大小为4,short类型的大小为2)

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include

int main()
{
	short s = 5;
	int a = 10;
	printf("%d\n", sizeof (s = a + 2));
	printf("%d\n",  s);
	return 0;
}

 结果为:

2021.12.12 史上最全操作符详解_第10张图片

我们发现就算我们放进一个 int 类型的值进去计算,s 的空间也不会变大,其大小仍然为2。

而且我们最后打印出来s的值并未发生改变,从而sizeof括号中放的表达式是不参与运算的。


 ~    按 位 取反

举例:

int a = -1;

int b= ~a;

(-1)二进制原码: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 

(-1)二进制反码: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0

(-1)二进制补码: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

   ~   按位取反 b= : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

           结果注意:        b的值为0,而且a的值不改变。


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

    注意:前置 和 后置  是不同的! 

   int b = a++(--);  后置++或--,先使用,再++或--

   int b = --(++)a;    前置++或--,先++或--,再使用

举例1:

#define _CRT_SECURE_NO_WARNINGS 1
#include

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

结果为:

2021.12.12 史上最全操作符详解_第11张图片

 举例2:

#define _CRT_SECURE_NO_WARNINGS 1
#include

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

结果为:

2021.12.12 史上最全操作符详解_第12张图片


*   间接访问操作符(解引用操作符)

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
	int a = 10;
	printf("%p\n", &a); // & 为取地址操作符   
	int* pa = &a;  // 这里的 * 代表 pa 为指针变量,pa是用来存放 a 的地址
	*pa = 20;  // * 间接访问操作符(解引用操作符)  pa 根据 a 的地址将 a 的值进行改变                
	printf("%d\n", a);
    return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第13张图片


(类型) 强制类型转换

举例1:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
	int a = (int)3.14; //将浮点型强制转化为整型
	printf("%d\n", a);
	return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第14张图片​ 


 关系操作符

   >        >=             <         <=   

(大于 大于等于    小于  小于等于   )

        !=              ==

(判断不等      判断等于  )

  十分简单明了 不做过多解释


逻辑操作符

注意:逻辑操作符仅用来判断真假,真为1,假为0。


 &&    逻辑与         (两数有一个为 0(假),便为0(假))

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
	int a = 1 ;
	int b = 2;
	int c = a && b; // 逻辑与   
	int d = a & b;   // 按位与   我们要注意区分
	printf("%d\n", c);
	printf("%d\n", d);
	return 0;
}

  结果为:

2021.12.12 史上最全操作符详解_第15张图片

 我们可以看到 c 的结果为1,代表两数都为真(都不为0)。


  ||      逻辑或         (两数有一个不为0 (真),便为1(真))

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
	int a = 2 ;
	int b = 0 ;
	int c = a || b;  // 逻辑或   
	int d = a | b;   // 按位或   我们要注意区分
	printf("%d\n", c);
	printf("%d\n", d);
	return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第16张图片

 我们可以看到 c 的结果为1,代表两数中有一个为真,则结果为真。


例题:

#define _CRT_SECURE_NO_WARNINGS 1
#include

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);
	return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第17张图片

 我们发现仅有a的值发生了改变+1,b和d 的值并未改变。

我们可以得出结论:

当从左到右执行的过程中,a++为后置++,先使用后++,但是逻辑与&&的判定为有0则为假,a最初的值便为0,所以先使用a的值,发现为假,从而直接结束执行,输出为假,导致第一个 && 后面的 b和d 都未执行就判定完了,从而输出的结果只有a的值加了1。

( ||   逻辑或 ,同样也遵守该原则,从左到右,如果出现不为0的数,结束执行,输出为真)

条件操作符(三目操作符) 

 exp1 exp2exp3    ( 书写形式 )

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
	int a = 3;
	int b = 0;

	if (a > 5)
		b = 1;
	else
		b = -1;  
	printf("%d\n", b);

	// 上面代码运用三目操作符来写便为:

	b= a > 5 ? 1 : -1;  // 从左到右,先a是否大于5,如果大于 则b的值为1,否则为-1
	printf("%d\n", b);
	return 0;
}

结果为: 

2021.12.12 史上最全操作符详解_第18张图片

逗号表达式 

exp1,exp2,exp3, ....expN

逗号表达式,就是用逗号隔开多个表达式。逗号表达式,从左到右依次执行。整个表达式的结果是最后一个表达式的结果。

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
	int a = 3;
	int b = 5;
	int c = 0;
	int d = (c = 5, a = c + 3, b = a - 4, c += 5);

	printf("%d\n", a);
	printf("%d\n", b);
	printf("%d\n", c);
	printf("%d\n", d);
	return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第19张图片

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

   [ ]   下标引用操作符

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%d\n", arr[4]);   //下标引用操作符
	                          // 操作数为2个  arr和4 
	return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第20张图片


 ( )函数引用操作符

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

int ADD(int x,int y)
{
	return x + y;
}

int main()
{
	int a = 10;
	int b = 20;
	//函数调用
	int ret = ADD(a, b); //()  函数调用操作符
	printf("%d\n", ret);
	return 0;
}

结果为

2021.12.12 史上最全操作符详解_第21张图片

结构成员访问操作符

  我们可以使用该操作符来访问我们自己所创建的自定义类型


.       结构体变量 . 成员名   

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

struct Book
{
	char name[20];
	char id  [20];
	int price;
};

int main()
{
	struct Book b = { "c语言", "c20211214", 55 };
	printf("书名:%s\n", b.name); 
	printf("书号:%s\n", b.id);
	printf("定价:%d\n", b.price);
	return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第22张图片


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

举例:

#define _CRT_SECURE_NO_WARNINGS 1
#include

struct Book
{
	char name[20];
	char id  [20];
	int price;
};

int main()
{
	struct Book b = { "c语言", "c20211214", 55 };
	struct Book* p = &b;   // 我们取 b 的地址

	printf("书名:%s\n", p->name);  // 指针 指向我们的对象 效果相同
	printf("书号:%s\n", p->id);
	printf("定价:%d\n", p->price);
	return 0;
}

结果为:

2021.12.12 史上最全操作符详解_第23张图片


以上便是关于 操作符详解 的全部内容了, 博主创作不易    喜欢可点个赞或收藏 激励博主哦!

谢谢浏览!(如有问题,请各位大神即使指出,我会及时纠正!)

你可能感兴趣的:(操作符详解,c语言)