> 文档中心 > 万字细文带你吃透操作符(C语言深入解剖篇)

万字细文带你吃透操作符(C语言深入解剖篇)


作者介绍:友友们好我是沐曦希,可以叫我小沐💕
作者主页:沐曦希的个人博客主页.🎉
作者的gitee:https://gitee.com/muxi-c-language.
零基础学习C语言系列:
🎈 https://blog.csdn.net/m0_68931081/category_11742786.html.
🎉小沐和友友们一样喜欢编辑,天天敲代码🤭,沉迷学习,日渐消瘦。很荣幸能向大家分享我的所学,和大家一起进步,成为合格的卷王。✨如果文章有错误,欢迎在评论区✏️指正。那么开始今天的学习吧!😘

文章目录

    • 🎈操作
    • 🎈算术操作符
    • 🎈移位操作符
        • ✨左移操作符
        • ✨右移操作符
            • 🎉逻辑移位
            • 🎉算术移位
    • 🎈位操作符
        • 🎉&--按位与
        • 🎉|--按位或
        • 🎉^--按位异或
    • 🎈赋值操作符
        • ✨复合赋值操作符
    • 🎈单目操作符
        • ✨单目操作符介绍
        • ✨sizeof 和 数组
    • 🎈关系操作符
    • 🎈逻辑操作符
    • 🎈条件操作符
    • 🎈逗号表达式
    • 🎈下标引用、函数调用和结构成员
        • ✨[ ] 下标引用操作符
        • ✨( ) 函数调用操作符
        • ✨访问一个结构的成员
    • 🎉写在最后

万字细文带你吃透操作符(C语言深入解剖篇)

🎈操作符

指令系统的每一条指令都有一个操作符,它表示该指令应进行什么性质的操作。不同的指令用操作符这个字段的不同编码来表示,每一种编码代表一种指令。

其中操作符分为:

  1. 算术操作符
    2.移位操作符
    3.位操作符
    4.赋值操作符
    5.单目操作符
    6.关系操作符
    7.逻辑操作符
    8.条件操作符
    9.逗号表达式
    10.下标引用、函数调用和结构成员

🎈算术操作符

+   -  *(乘)  /(除)   %(取模)

注意:1.✏️除了% 操作符之外,其他的几个操作符可以作用于整数和浮点数

#includeint main(){int a = 12;int x = 5;float b = 7.0;float c = -6.0;float d = b + c;float e = b - c;float f = b * c;float g = b / c;int ret = a % x;printf("d=%f\ne=%f\nf=%f\ng=%f\nret=%d", d, e, f, g, ret);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
2.✏️对于/ 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法

#includeint main(){int a = 20;int b = 10;int c = 20.0;int d = 10.0;int x = a / b;float y = c / d;printf("x=%d\ny=%f", x, y);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
3.✏️% 操作符的两个操作数必须为整数。返回的是整除之后的余数

#includeint main(){int a = 8;int b = 3;int c = a % b;printf("%d", c);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

🎈移位操作符

移位操作符针对的是二进制,所以移动的是二进制,每次运算时,第一步需要转换成对应的二进制,再进行移位。

<< 左移操作符>> 右移操作符注:移位操作符的操作数只能是整数。

✨左移操作符

移位规则:

左边抛弃、右边补0

#includeint main(){int num = 2;printf("num<<1=%d", num << 1);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

万字细文带你吃透操作符(C语言深入解剖篇)
当num=-2时:

#includeint main(){int num = -2;printf("num<<1=%d", num << 1);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
左移一位相当于该数字乘于2,

✨右移操作符

右移操作符相对复杂一点。分为逻辑移位和算术移位。在转换成二进制时,二进制的第一个数字表示正负,即当第一个数字为0时,该数字为正,为1时,该数字为负
例如:
万字细文带你吃透操作符(C语言深入解剖篇)
✏️小知识:整数的二进制表示有三种方式:原码,反码,补码
正整数的原码,反码和补码相同。
负整数的原码,反码和补码不相同。
其中在存储时候,存储的是补码。

万字细文带你吃透操作符(C语言深入解剖篇)

🎉逻辑移位

移位规则:

左边用0填充,右边丢弃

#includeint main(){int num = -2;int a = num >> 1;printf("%d", a);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

🎉算术移位

移位规则:

左边用原该值的符号位填充,右边丢弃

#includeint main(){int num = -2;int a = num >> 1;printf("%d", a);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
万字细文带你吃透操作符(C语言深入解剖篇)
小沐用的编译器支持的是算术右移。
警告⚠ :
对于移位运算符,不要移动负数位,这个是标准未定义的。(浮点数也不行)

例如:

int num = 10;num>>-1;//error

右移一位相当于除与2。

🎈位操作符

位操作符是二进制的运算,故与移位操作符一样,运算的第一步应讲操作数转换成二进制位操作符只适用于整型。
位操作符有:

& //按位与| //按位或^ //按位异或

注:他们的操作数必须是整数。

🎉&–按位与

运算规则:有零则为零,同为一才为一。✏️

0&0=0 1&0=0 1&1=0 0&1=0

例如:

#includeint main(){int a = 3;int b = -5;int c = a & b;printf("%d", c);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
万字细文带你吃透操作符(C语言深入解剖篇)

🎉|–按位或

运算规则:有1则为1,同为零才为零。✏️

1|1=1 1|0=1 0|0=1 0|1=1

例如:

#includeint main(){int a = 3;int b = -5;int c = a | b;printf("%d", c);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
万字细文带你吃透操作符(C语言深入解剖篇)

🎉^–按位异或

运算规则:相同为0,不相同为1。✏️

1^0=1 0^1=1 0^0=0 1^1=0

例如:

#includeint main(){int a = 3;int b = -5;int c = a ^ b;printf("%d", c);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
万字细文带你吃透操作符(C语言深入解剖篇)
练习:

不能创建临时变量(第三个变量),实现两个数的交换。

//代码一#includeint main(){int a = 3;int b = 5;printf("交换前:a=%d,b=%d\n", a, b);a = a + b;b = a - b;a = a - b;printf("交换后:a=%d,b=%d\n",a, b);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
代码一容易溢出,当a和b都很大时,容易导致a=a+b溢出。
故:

//代码二#include int main(){int a = 10;int b = 20;a = a ^ b;b = a ^ b;a = a ^ b;printf("a = %d b = %d\n", a, b);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
通过:

3^3=0   0^5=5   a^a=0  0^a=a即3^3^5=0^5=5    3^5^3=5

则按位异或支持交换律。
万字细文带你吃透操作符(C语言深入解剖篇)

🎈赋值操作符

在写代码时候可以通过赋值操作符给变量赋值,从而得到想要的结果。

int weight=120//初始化weight=90//赋值//注:初始化和赋值不一样int high=175//初始化high=185///赋值//赋值操作符可以连续使用,比如:int a = 10;int x = 0;int y = 20;a = x = y+1;//连续赋值//先x=y+1=20+1=21,后a=x=21//这样的代码感觉怎么样?//那同样的语义,你看看:x = y+1;a = x;//这样的写法是不是更加清晰爽朗而且易于调试。

✨复合赋值操作符

复合赋值操作符的运算规则和前面的类似。

+=    -=*=    /=      %=>>=   <<=&=    |=      ^=

这些运算符都可以写成复合的效果。

int a+=5//a=a+5int a-=5//a=a-5int a*=5//a=a*5int a/=5//a=a/5int a%=5//a=a%5int a>>=5//a=a>>5int a<<=5//a=a<<5int a&=5//a=a&5int a|=5//a=a|5int a^=5//a=a^5

🎈单目操作符

单目操作符只有一个操作数。

✨单目操作符介绍

! 逻辑反操作- 负值+ 正值& 取地址sizeof 操作数的类型长度(以字节为单位)~ 对一个数的二进制按位取反-- 前置、后置--++ 前置、后置++* 间接访问操作符(解引用操作符)(类型) 强制类型转换
//! 逻辑反操作#includeint main(){int flag = 1;if (!flag)//flag为假,进入if语句{printf("是沐曦希呀\n");}if (flag)//flag为真,进入if语句{printf("是小沐呀\n");}return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

// -(负值)  +(正值)//负负得正  正正得正  负正得负#includeint main(){int a = -10;int b = +a;int c = -a;printf("b=%d\nc=%d\n", b, c);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

//&--取地址操作符#includeint main(){int a = 0;printf("%p\n", &a);//打印a的地址return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

//sizeof 操作数的类型长度(以字节为单位)#includeint main(){int a = 10;int n = sizeof(a);//计算的是a所占的内存的大小,单位是字节printf("n=%d\n", n);//szieof是一个单目操作符//计算的是变量所占内存空间的大小int set = sizeof(int);//计算类型所创建的变量所占据空间的大小,单位是字节printf("set=%d\n", set);int sz = sizeof a;//操作符可以省略变量的(),但是类型不能省去printf("sz=%d\n", sz);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

//~ 对一个数的二进制按位取反//即将0变成1,1变成0#includeint main(){int a = 0;printf("%d\n", ~a);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
万字细文带你吃透操作符(C语言深入解剖篇)

#includeint main(){int a = 3;printf("%d\n", ~a);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

//++ 前置、后置++#includeint main(){int a = 3;int b = ++a;//前置++,先++,后使用//a=a+1,b=aint c = a++;//后置++,先使用,后++//c=a,a=a+1printf("a=%d,b=%d,c=%d", a, b, c);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

//-- 前置、后置--#includeint main(){int a = 3;int b = --a;//前置--,先--,后使用//a=a-1,b=aint c = a--;//后置--,先使用,后--//c=a,a=a-1printf("a=%d,b=%d,c=%d", a, b, c);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

#includeint main(){int a = 10;printf("%d\n", a--);//后置--printf("%d\n", a);int i = 0;for (i = 0; i < 3; i++){printf("%d ", i);}printf("\n");for (i = 0; i < 3; ++i){printf("%d ", i);}//在for语句中前置和后置无区别,只是前置效率高。return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

//* 间接访问操作符(解引用操作符)//通常与指针一起使用#includeint main(){int a = 10;int* p = &a;*p = 20;//a=20printf("a=%d\n", a);printf("*p=%d\n", *p);printf("p=%p\n", p);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
万字细文带你吃透操作符(C语言深入解剖篇)

//(类型) 强制类型转换//即强制将一种类型转换成另一种类型#includeint main(){int a = (int)3.14;printf("%d\n", a);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

✨sizeof 和 数组

初学C语言时,经常用到sizeof来求数组的大小和元素个数等。
需要区别strlen和sizeof。
sizeof是一个单目操作符,不是一个函数。
strlen是一个库函数,头文件为string.h,是用来求字符串的长度。
例如:

#include#includevoid test1(int arr[]){printf("arr[]=%d\n", sizeof(arr));}void test2(char ch[]){printf("ch[]=%d\n", sizeof(ch));}int main(){int arr[10] = { 0 };char ch[10] = { 0 };printf("arr[10]=%d\n", sizeof(arr));printf("ch[10]=%d\n", sizeof(ch));test1(arr);test2(ch);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

注意:1.指针变量不管所指的变量是什么类型,其大小都是4或者8个字节。✏️
当配置是x86时,大小为4个字节;配置为x64时,大小为8个字节。
2.数组作为参数传参时候,传的是数组的首元素的地址。

小知识:

//strcmp是用来比较字符串的内容//strcpy是用来拷贝内容的#include#includeint main(){char arr[10] = { 0 };char ch[5] = "abcd";strcpy(arr, "母亲节快乐!");printf("%d\n", sizeof(ch));printf("%d\n", strlen(ch));if (~strcmp(ch, "abc")){printf("祝小沐的妈妈");}printf("%s\n", arr);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数。基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1str2,则返回正数。
strlen是用来求字符串的长度。

strlen遇到’\0’则停止并返回,只会计算‘\0’之前的元素个数。
sizeof可以求变量(类型)所占空间的大小。

🎈关系操作符

>>=<<=!= 用于测试“不相等”== 用于测试“相等”

这些关系运算符比较简单,但是我们要注意一些运算符使用时候的陷阱。
例如:在编程的过程中把==写成=,导致错误

#includeint main(){int a = 0;if (a = 1){printf("hehe\n");}if (a == 2){printf("haha\n");}return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

if("abc"=="abcdef")//这样写是比较两个字符串的首字符的地址//比较字符串用strcmp

🎈逻辑操作符

逻辑操作符只关注真假,真则返回1,假则返回0。

&& 逻辑与|| 逻辑或

区分 逻辑与(&&) 和 按位与(&)
区分 逻辑或(||) 和 按位或(|)

#includeint main(){printf("%d\n", 1 & 2);printf("%d\n", 1 && 2);printf("%d\n", 1 | 2);printf("%d\n", 1 || 2);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

//练习1#include int main(){int i = 0, a = 0, b = 2, c = 3, d = 4;i = a++ && ++b && d++;//后置++,因为a=0,即为假,故后面的++b和d++不会运行,只运行a=a+1printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

//练习2#include int main(){int i = 0, a = 0, b = 2, c = 3, d = 4;i = a++||++b||d++;//因为前置++b,b=3,故为真,即运行a++,++b和d++printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)
&&–左边为假,即为假,则右边就不用计算了。
||–左边为真,即为真,则右边就不用计算了。

🎈条件操作符

条件操作符也叫三目操作符

exp1 ? exp2 : exp3

万字细文带你吃透操作符(C语言深入解剖篇)

//使用条件表达式实现找两个数中较大值。#includeint main(){int a = 10;int b = 20;printf("%d\n", a > b ? a : b);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

if (a > 5)b = 3;elseb = -3;//转换成条件表达式#includeint main(){int b = 0;int a = 0;b = (a > 5 ? 3 : -3);return 0;}

🎈逗号表达式

exp1, exp2,exp3...expN

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

//代码1int a = 1;int b = 2;int c = (a>b, a=b+10, a, b=a+1);//逗号表达式//c是多13//代码2if (a =b + 1, c=a / 2, d > 0)//if(d>0)//代码3a = get_val();count_val(a);while (a > 0){//业务处理     a = get_val();     count_val(a);}//如果使用逗号表达式,改写:while (a = get_val(), count_val(a), a>0){     //业务处理}

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

✨[ ] 下标引用操作符

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

#includeint main(){int arr[10] = { 0 };arr[7] = 8;//[]是下标引用操作符(双目操作符:arr和7是操作数)7[arr] = 9;//arr[7]-->*(arr+7)-->*(7+arr)-->7[arr]//arr是数组的首元素地址//arr+7就是跳过7个元素,指向第8个元素。//*(arr+7)就是第8个元素printf("%d\n", arr[7]);printf("%d\n", 7[arr]);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

✨( ) 函数调用操作符

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

#include void test1(){printf("hehe\n");}void test2(const char* str){printf("%s\n", str);}int main(){test1(); //实用()作为函数调用操作符。//操作数只有一个,即为test1test2("hello");//实用()作为函数调用操作符。//操作数有两个,test2和"hello"。return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

int c=Add(a,b);//()是函数调用操作符,操作数:Add,a,b//函数调用操作符()的操作数至少有一个,即为函数名

✨访问一个结构的成员

. 结构体.成员名-> 结构体指针->成员名
#include struct Stu{char name[10];int age;char sex[5];double score;};void set_age1(struct Stu stu){stu.age = 18;}void set_age2(struct Stu* pStu){pStu->age = 18;//结构成员访问}int main(){struct Stu stu;struct Stu* pStu = &stu;//结构成员访问stu.age = 20;//结构成员访问set_age1(stu);pStu->age = 20;//结构成员访问set_age2(pStu);return 0;}
#include #includestruct Stu{char name[20];int age;double score;};void set_stu(struct Stu* ps){//strcpy((*ps).name, "zhangsan");//(*ps).age = 20;//(*ps).score = 100.0;strcpy(ps->name, "zhangsan");ps->age = 20;ps->score = 100.0;}void print_stu(struct Stu* ps){printf("%s %d %lf\n", ps->name, ps->age, ps->score);}int main(){struct Stu s = { 0 };set_stu(&s);print_stu(&s);return 0;}

万字细文带你吃透操作符(C语言深入解剖篇)

🎉写在最后

那么今天的学习就到这里了。友友们觉得不错的可以给个关注,点赞或者收藏哦!😘感谢各位友友们的支持。以下的代码希望各位大佬们自行检验哦,毕竟亲手操作让记忆更加深刻。

你的❤️点赞是我创作的动力的源泉
你的✨收藏是我奋斗的方向
你的🙌关注是对我最大的支持
你的✏️评论是我前进的明灯
创作不易,希望大佬你支持一下小沐吧😘

下一期见了!