本篇目的:
- 认识和熟练掌握操作符
- 分析表达式求值
关系操作符:两个数之间的大小关系
#include
int main()
{
int a=0;
//等于
if(a==0)//条件为真
printf("hehe\n");
//赋值
if(a=0)//0是假,所以不打印
printf("hello\n");
return 0;
}
运行结果:
hehe
空
注意:
等于(==)
赋值操作符(= )
这两个是不同的,写代码时注意区分;
逻辑操作符内容:
运算法则:
- 逻辑与:并且的意思,一假则为假,两个都为真才为真
- 逻辑或:或者的意思,一真则为真,两个都为假才为假
- 逻辑运算符的计算结果是0或1这两个结果,不要与按位操作符搞混
#include
int main()
{
int a=5;
int b=10;
if(a&&b)
printf("hehe\n");
a=0;
if(a&&b)
printf("haha\n");
b=0;
if(a&&b)
printf("heihei\n");
return 0;
}
运行结果:
hehe
空
空
#include
int main()
{
int a=5;
int b=10;
if(a||b)
printf("hehe\n");
a=0;
if(a||b)
printf("haha\n");
b=0;
if(a||b)
printf("heihei\n");
return 0;
}
运行结果:
hehe
haha
空
为了加深一下印象,我们看看这两段代码(答案放在两段代码后面):
逻辑与的代码运算:
#include
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);
printf("i = %d\n",i);
return 0;
}
逻辑或的代码运算
#include
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);
printf("i = %d\n",i);
return 0;
}
逻辑与代码的运行结果:
a = 1
b = 2
c = 3
d = 4
i = 0
对于逻辑与操作符,一假则假,只要前面算到假那么后面的全都不计算,即算到有一个0就停止计算后面的所有
逻辑或代码运行的结果:
a = 1
b = 3
c = 3
d = 4
i = 1
为什么是这个结果呢?
总结:
对于逻辑或操作符,一真则真,只要前面算到真,那么后面全都不计算,即算到有一个不为0的数就停止计算后面的所有
条件操作符的写法如下,条件表达式也称三目表达式,其中exp1是表达式1,exp2是表达式2,exp3是表达式3。
- 表达式1为真,执行表达式2,表达式2的结果为整个条件表达式的结果
- 表达式1为假,执行表达式3,表达式3的结果为条件表达式的整个结果
#include
int main()
{
int a=3;
int b=6;
int max=(a>b?a:b);
printf("%d\n",max);
return 0;
}
运行结果:
6
逗号表达式的写法:
从左向右依次执行,整个表达式的结果是最后一个表达式的结果。
#include
int main()
{
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);
printf("%d\n",c);
}
运行结果:
13
1.下标引用操作符
符号:[ ],必须有数组名和下标两个操作数
一般写法:
#include
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d\n%d\n",arr[0],arr[9]);
printf("%d\n%d\n",0[arr],9[arr]);//这个写也是正确的,因为[]的操作数是数组名和下标,但是可读性差
return 0;
}
运行结果:
1
10
1
10
2.函数调用操作符
符号:(),至少有函数名这一个操作数
一般写法:
#include
#include
int main()
{
char arr[]="abcdefg";
int c=strlen(arr);//调用strlen函数
printf("%d\n",c);
return 0;
}
运行结果:
7
3.访问一个结构体成员
符号:.(点) 和 ->(箭头)
一般写法:
自定义类型:结构体,枚举,联合体
今天先大概认识一下,后面会详细说明结构体
#include
struct book//结构体类型
{
char name[20];
char author[20];
int price;
};
int main()
{
struct book a = { "c语言","作者",66 };//创建结构体变量并初始化
printf("《%s》 %s %d",a.name,a.author,a.price);//通过结构体变量访问
struct book* p=&a;//创建结构体指针变量
printf("《%s》 %s %d",(*p).name,(*p).author,(*p).price);//解引用操作符也是可以访问的,太麻烦
printf("《%s》 %s %d",p->name,p->author,p->price);//通过结构体指针变量访问
return 0;
}
运行结果:
《c语言》 作者 66
《c语言》 作者 66
《c语言》 作者 66
- 表达式求值的顺序一部分是由操作符的优先级和结合性决定。
- 有些表达式的操作数在求值的过程中可能需要转换为其他类型。
- C的整型算术运算总是至少以默认整型类型的精度来进行的。
- 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升
- 整形提升是按照变量的数据类型的符号位来提升的
总结:为了适应CPU,char类型和short类型在使用之前会自动转换为int类型或者unsigned int类型
#include
int main()
{
char a=3;
char b=127;
char c=a+b;
printf("%d\n",c);
return 0;
}
答案会是130吗?
运行结果:
-126
int main()
{
char a = -3;
char b = 127;
char c = a - b;
printf("%d", c);
return 0;
}
运行结果?
-130吗?
正确结果:126
- 如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。
- 如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。
int main()
{
int a = 4;
float b = 7.5;
a + b;//int类型会向上转换为float,结果是11.500000
double c = 2.5;
b + c;//float类型会向上转换为double类型,结果是10.000000
return 0;
}
操作符的属性主要有三个:
- 操作符的优先级
- 操作符的结合性
- 是否控制求值顺序
两个相邻的操作符先执行哪个?
取决于他们的优先级,如果两者的优先级相同,取决于他们的结合性。
越靠上优先级越高
int main()
{
int a = 1;
int b = 3;
int c = 7;
int d = a * b + c / a;//相邻两个操作符的优先级*大于+,/大于+,所以先计算乘法再计算除法最后计算加法
printf("%d", d);
return 0;
}
运行结果:
10
int main()
{
int a = 1;
int b = 3;
int c = 7;
int d = a + b + c;//相邻操作符优先级相同,看结合性,+是L-R从左向右计算
printf("%d", d);
return 0;
}
运行结果:
11
- 是否控制求值顺序,比如&&只要有真后面的就不计算了
- 如果不清楚优先级的高低,可以加()
有了操作符的这三个属性,不一定就能确定表达式的计算路径
int fun()
{
static int count = 1;
return ++count;
}
int main()
{
int answer;
answer = fun() - fun() * fun();//不知道那个函数先调用,所以计算路径不确定,可能是-4,可能是-10,不同的编译器可能有不同的结果
printf( "%d\n", answer);
return 0;
}
以上就是操作符的所有内容了,如果喜欢本篇,不妨点个赞,如果有什么问题,欢迎来评论区一起讨论,如果想了解更多c语言的知识,关注我,我会分享更多有用的知识。
拜拜!!!