目录
操作符详细介绍:
一,算术操作符
二.移位操作符(接下来所有的数都假设在32位机器下运算)
位操作符
按位异或比较难记,我们要多熟悉熟悉哦
赋值操作符
单目操作符
++和--操作符
逻辑操作符
表达式求值:
运算符的优先性和结合性
操作符贯穿我们C语言的各个部分,接下来我们进行各式各样的操作符的详细介绍以及各种表达式的求值,希望能帮助大家十分熟悉地使用操作符
①算术操作符
②移位操作符
③位操作符
④赋值操作符
⑤单目操作符
⑥关系操作符
⑦逻辑操作符
⑧条件操作符
⑨逗号表达式,下标引用,函数调用还有结构成员操作符
接下来我们依次详细介绍
首先我们来讲C语言中有两个单目算术运算符即+ (正) -(负),还有五个双目运算符,双目运算符中,乘除取余运算符比加减运算符优先级更高。一讲双目算术操作符,就是最简单的 加减乘除 还有 取余。
+ - * / %
(注:这里都是双目操作符)
注意一下:这里我们只需要讲一下需要注意的算术操作符里的除号不能写成➗,而是 / 才对
如果用除法操作符,如果其中一个数字为浮点数,所求出的结果也为浮点数(默认保留五位小数点)
代码演示:
如果我们想要少保留一些小数,在 %f 的 f 前加上.(保留小数位)。例如
这里 . 后是数字1,所以保留一位小数。
还有就是 % 这是取模操作符,就是我们小学所学的余数,比如14余上10结果为4。
上代码深入理解
#include
int main()
{
int i = 15;
printf("%d %d", i / 10, i % 10);
return 0;
}
运行结果为 1和5,这是整型之间的算术操作,切记,取余运算的两个数都必须为整数。如果是浮点数他就会报错。
就像下边这样
1,左移操作符
移位规则:左边抛弃,右边补零。
2,右移操作符
右移运算分为两种
⭐1,逻辑移位
左边用零填充,右边丢弃
2.算术移位
左边用原该值的符号位填充
当然对于移位操作符,不要移动负数位,这个是标准未定义的
以下这几个操作符都是双目操作符
& //按位与
| //按位或
^ //按位异或
注:他们的操作数必须是整数
就按照上述例子来讲,我们仔细分析以下结果是如何得出来的
首先我们来分析a的结果是如何求出的
要知道
按位与还有一个用途就是取特定位,就比如要求54的后四位,只需要将54与后四位都是1的数按位与,如果要求后五位,那就给后五位都是 1 的数按位与
54的二进制序列为
00000000000000000000000000110110和
00000000000000000000000000001111按位与
结果为00000000000000000000000000000110
后四位就取出来了,即为0110
接下来我们看b,按位或(|)
就像上面那样,按位或的作用就是可以把某些位变成 1 ,很简单滴,只需要按位或上这些位都是1的数就可以啦
这里我们看结果是如何求出 c = 3滴
这里我们上边介绍了按位异或(^)的功能就是使参与运算的两个数的二进制位相异时为 1 ,相同为 0 .
异或操作符(^)的主要用途就是能使 特定的位 翻转,例如我们要将127的后5位翻转,只需要将127与后五位都是1的数按位异或
00000000000000000000000001111111
与00000000000000000000000000011111按位异或结果为
00000000000000000000000001100000
按位异或还可以在不用临时变量的情况下实现两个变量的互换,很是难以想到。
我们看代码
为什么这么奇妙嘞
我们来看他是如何做到的
在程序中常常遇到的 = 就是所谓的赋值操作符
这里值得我们注意的是,并不是所有表达式都可以作为左值,如常数只可以作为右值。
复合操作符(这个蓝色字体真好看)
+= -= *= /= %=
>>= <<= &= |= ^=
具体效果是怎么样的呢?
只举一例,其中+=的效果
int main()
{
int x = 10;
x = x + 1;
printf("%d\n", x);
int y = 10;
y += 1;
printf("%d\n", y);
return 0;
}
运行结果可以发现,两个数最终的值都为 11.他们两种表达方式的效果相同。
其他的呢,加等和加上某个数一样,其他的呢?懂滴都懂
① ! 逻辑反操作
② - 负值
③ + 正值(几乎不用,可以省略)
④ & 取地址操作符
⑤ sizeof 操作数类型的长度(以字节为单位)没错,这个小伙也是操作符
⑥ ~ 对一个数的二进制进行按位取反
⑦ -- 分为前置--,和后置--
⑧ ++ 和--一样
⑨ * 间接访问操作符(解引用操作符)
逻辑反操作 !
通常使用单目操作符!把一个变量的数值转换为相应的逻辑真值或假值,也就是0和1.
比如
result = !num;
如果num非0,则result为零,如果num为零,则result为1.
负值正值就是正号负号,不必多言
&取地址符号可以找到变量字符串函数之类的地址
sizeof也是一个操作符,可以求出变量所占空间的大小,但是不能直接sizeof后直接加变量类型。
int main()
{
int a = -10;
int* p = NULL;
printf("%d\n", !2);
printf("%d\n", !0);
a = -a;
p = &a;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(int));
printf("%d\n", sizeof a);
//printf("%d\n", sizeof int);
return 0;
}
sizeof和数组
我们看代码
在x86环境下,因为传过去的是数组名,而sizeof后如果是数组名,那就代表的是整个数组,char类型占1个字节,int类型占4个字节,而数组里都是十个元素,所以结果是40和10,因为地址储存形式都是整型,所以后边两个结果都是4。
前边我们讲了++和--分为前置和后置两种
我们先看前置++和前置--
我们可以发现,前置++和前置--都是加1或者减1后再赋值
现在我们看后置++和后置--的区别
很明显,后置++和后置—是先赋值,后进行加1减1的操作
关系操作符
> >= < <=
!=(用于测试“不相等”) ==(用于测试相等)
以上的操作符都比较简单,但是要注意在判断相等时两个等号不能只写一个。
&& 逻辑与
|| 逻辑或
这里我们要分清楚按位与按位或和逻辑与逻辑或的区别
按位与按位或是与二进制有关的
而逻辑与逻辑或就是生活中我们常说的 或者 和 并且。很简单哒,这里就不举什么例子咯
接下来讲一讲条件操作符(三目操作符)很多时候可以让代码简单许多。
格式为 exp1 ? exp2 : exp3
它是如何使用的呢?
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
if (a > 5)
b = 3;
else
b = -3;
printf("%d\n", b);
return 0;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d", &a);
(a > 5) ? (b = 3) : (b = -3);
printf("%d\n", b);
return 0;
}
运行后我们会发现这两段代码的作用是相同的,但明显第二种更加简洁,exp1是一个判断,如果exp1为真,则执行exp2,若为假,则执行exp3。
逗号表达式
表现形式为exp1,exp2,exp3,exp4,……
逗号表达式,顾名思义就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次进行计算,整个表达式的结果是最后一个表达式的结果,我们可以举几个例子来更好地理解都好表达式的作用。
下标引用,函数调用和结构成员
1,[ ]下标引用操作符
下标引用操作符有两个操作数:数组名,索引值
int arr[10]
arr[9] = 10;
此时 [] 的两个操作数分别为 arr 和 9。
2,函数调用操作符()
接受一个或者多个操作数,第一个操作数是函数名,剩余的操作数都是传递给函数的参数
数组方面的知识可以在这里熟悉一下。
接下来我们直接看代码
void test1()
{
printf("hehe\n");
}
void test2(const char *str)
{
printf("%s\n", str);
}
int main()
{
test1();//函数调用操作符。
test2("hello world");
return 0;
}
结构体成员访问操作符有两种
1,点操作符(.)形式为 结构体 . 成员名
2,箭头操作符(->) 结构体指针->成员名
代码演示
//首先我们要创建一个结构体
//假设是一个学生的信息
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_agel(stu);
pstu->age = 20;
set_age2(pstu);//这里传过去的是地址
return 0;
}
⭐然后嘞,这里我们来说说表达式求值
表达式求值的顺序是由操作符的优先级和结合性决定。
有些表达式的操作符在求值的过程中需要转换为其他类型。所以要了解了解隐式类型转换
c语言的整型算术运算总是至少以缺省整型类型的精度来进行的,为了获取这个精度,表达式中的字符和短整型操作数在使用之前被转化为普通整型,这种转换被称为整型提升。之所以称为隐式,是因为这是编译器自己在后台完成的。
例如有三个char类型的数,在参与运算前都会被提升为普通整型,然后再执行运算。运算完成后再截断。
如何进行整型提升的呢?
整型提升是按照变量的符号位进行滴,看看下图,你就明白
只要参加运算,就会产生整型提升, 只要参加运算,就会产生整型提升, 只要参加运算,就会产生整型提升(重要的事说三次)
运行结果可以发现,c只要参与表达式运算,就会发生整型提升,表达式+c和-c就会发生整型提升,所以求出的是4个字节,但是sizeof(c)就是1个字节。
最后我们来讲一讲上面我们所说的操作符的优先级
操作符的属性
复杂表达式的求值有三个影响的因素
1,操作符的优先性
2,操作符的结合性
3,是否控制求值顺序
这部分在不同编译器中有些复杂的表达式的优先级和结合性不同,同一表达式得出的结果也大不相同。
1.算术运算符的结合性
从上图看,我们发现()的优先级很高,所以我们可以用括号提高部分运算的优先级,就比如
a*(b+c),先进行加法计算再进行乘法计算。
2.算术运算符的结合性
当算术运算符的优先级相同时,结合方向为 从左向右
就比如:a+b-c
先进行a+b再进行减c操作。
本章就结束啦,欢迎友友门交流学习哦
才疏学浅,有问题及时指出哈!