【C语言】操作符详解(下)

目录

前言

1.sizeof

 2.自增和自减(++、- -)

​编辑3.逻辑操作符

4.条件操作符(exp1?exp2:exp3)

5.逗号表达式(exp1,exp2,exp3,……)

6.地址操作符(*、&)

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

7.1[]下标引用操作符

7.2()函数调用操作符

7.3访问一个结构成员

 8.关系操作符

 9.操作符的属性

总结


前言

操作数详解(上)的链接:

http://t.csdnimg.cn/Nwd9i

1.sizeof

sizeof是求操作数的类型长度(以字节位单位)

sizeof(类型名),类型名也可以是变量的名字。

有好多人认为sizeof是函数,但是函数在调用时必须带有()才能被使用,但sizeof在使用时可以不带(),所以sizeof其实是一个操作符。

注意:只有在用变量名时才能省略(),其他情况不能省略。

sizeof在涉及到数组时要注意 。

#include <stdio.h>
void test1(int arr[])
{
 printf("%d\n", sizeof(arr));//(2)
}
void test2(char ch[])
{
 printf("%d\n", sizeof(ch));//(4)
}
int main()
{
 int arr[10] = {0};
 char ch[10] = {0};
 printf("%d\n", sizeof(arr));//(1)
 printf("%d\n", sizeof(ch));//(3)
 test1(arr);
 test2(ch);
 return 0;
}

问 (1)、(2)输出什么,(3)、(4 )输出什么

答案:(1)、(2)输出40、4或8,(3)、(4 )输出10,4或8

为啥是4或8呢,是因为arr传过去的是数组首元素的地址,函数用指针接收的,所以sizeof求的是指针的类型长度,在32位情况下是4个字节,在64位情况下是8个字节。

 2.自增和自减(++、- -)

自增和自减有前置(++i,- -i)和后置(i++,i- -)之分,前置是先++(- -)再使用操作数,后置是先使用操作数再++(- -)。

3.逻辑操作符

&&  逻辑与

||     逻辑或

!    逻辑非

逻辑与运算规则:全真为真,有假为假。
逻辑或运算规则:全假为假,有真为真。
逻辑非运算规则:是真为假,是假为真。

C语言中零表示假,非零表示真。

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

按位与和按位或作用的是二进制位,而逻辑与和逻辑或作用的是表达式的真假。
例子:

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

逻辑与和逻辑或都有短路这一特点,如果左边的值可以确定整个逻辑表达式的值右边就不再计算了。

 例子:

int main()
{
    int i = 0, a = 0, b = 2, c = 3, d = 4;
    i = a++ && ++b && d++;
    printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
    return 0;
}
//程序输出的结果是什么?

答案:

我们可以看到只有a自增1了,其他的自增都没有执行,这就体现了逻辑与的短路,因为a是后置++,先使用a=0,逻辑与有假为假,所以右侧的++b不用计算也知道a++&&++b的值为0 ,所以++b就被短路了,没有执行,后边的d++也是一样。

通过我的讲解,大家也可以练习一下,看看下面的代码结果是什么,可以把答案打在评论区。

int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	i = a++||++b||d++;
	printf("a = %d\nb = %d\nc = %d\nd = %d\n", a, b, c, d);
	return 0;
}

4.条件操作符(exp1?exp2:exp3)

运算规则:表达式1的值为真,结果就为表达式2的值,为假,结果就为表达式3的值。

if ( a > 5 )
        b = 3 ;
else
        b = - 3 ;
转换成条件表达式,是什么样?

答案:a>5?b=3:b=-3;

我们可以看到一些简单的if else语句可以用条件操作符替代来简化代码。

5.逗号表达式(exp1,exp2,exp3,……)

逗号表达式,就是用逗号隔开的多个表达式。 逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
例子:
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);
//c的值为多少

有的人认为c的值为2,但其实是13,虽然逗号表达式的结果为最后一个表达式的结果,但是前面表达式的结果对后面表达式的值也有影响。

逗号表达式也有简化代码的作用

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

6.地址操作符(*、&)

如果你想得到一个变量的地址,你可以使用&(取地址操作符)。

如果你想得到一个地址指向位置的内容可以使用*(解引用操作符)

例子:

1.得到变量地址

int a= 0;

int* p = &a;

//这样指针p就得到了变量a的地址。

2.得到地址内容

int a= 0;

int* p = &a;

int  b = *p;//与b = a效果一样

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

7.1[]下标引用操作符

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

7.2()函数调用操作符

接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数
的参数。
#include <stdio.h>
 void test1()
 {
 printf("hehe\n");
 }
 void test2(const char *str)
 {
 printf("%s\n", str);
 }
 int main()
 {
 test1();            //实用()作为函数调用操作符。
 test2("hello bit.");//实用()作为函数调用操作符。
 return 0;
 }

7.3访问一个结构成员

 . 结构体.成员名

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

当我们创建了一个结构体变量时,我们想访问里面的成员变量就可以使用  . 来访问,当我们通过函数把地址传给结构体指针时,可以通过->来访问成员变量。

例子: 

#include <stdio.h>
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;
}

 8.关系操作符

>
>=
<
<=
!=   用于测试 不相等
==       用于测试 相等  
这些关系运算符比较简单,但是我们要注意一些运算符使用时候的陷阱。

警告: 在编程的过程中== =不小心写错,导致的错误。

 9.操作符的属性

复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。

但是就算我们知道了操作符的优先级,我们还是不能准确的判断表达式的结果。

例子如下:

一些问题表达式

代码1:a * b + c * d + e * f 

注释:代码1在计算的时候,由于*+的优先级高,只能保证*的计算是比+早,但是优先级并不
能决定第三个*比第一个+早执行。

所以表达式的计算机顺序就可能是:

a*b
c*d
a*b + c*d
e*f
a*b + c*d + e*f
或者:
a*b
c*d
e* f
a*b + c*d
a*b + c*d + e*f

代码2:c + --c;

注释:同上,操作符的优先级只能决定自减--的运算在+的运算的前面,但是我们并没有办法得
知,+操作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义
的。

 通过上边的几个例子,我们也感受到了,就算知道了优先级吗,有些表达式也是不能确定的的,所以我们以后写代码,尽量少写问题代码,把表达式写的简洁好理解,可以使用括号来确定运算顺序。

操作符优先级表

总结

到这里操作符的讲解就都结束了,希望各位读者能有所收获,感谢大家的阅读,欢迎各位大佬在评论区留言哦~!!!

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值