来接续进行我们的操作符详解,本期是最后一期,相信从1看到5的小伙伴们一定对于操作符有了不少收获,好的,废话不多说,继续:
1.三目操作符(条件操作符)
三目操作符顾名思义,三个操作数嘛,其实就类似与一个简化版的if,else语句。三目操作符的形式为:exp1 ? exp2 : exp3。这里的exp指的是表达式。举个简单的例子:
if (a > 1)
return 1;
else
return 0;
//它就等价于:
a>1 ? 1 : 0
“a>1 ? 1 : 0”这个式子的意思就是如果a>1就返回1,否则返回0。从本质来说,三目操作符本身也是一个表达式,整个表达式的值就是“:”前后两个表达式之一的值,可以把三目操作符作为条件放入if等语句中。
做个小练习,用三目操作符写一个判断两个数谁大的小程序:
int main()
{
int a, b;
printf("请输入两个数n");
scanf("%d%d", &a, &b);
printf("%d和%d里,最大是%dn", a, b, (a>b ? a : b));
return 0;
}
效果图:
2.逗号表达式:exp1, exp2, exp3......, expN
所谓逗号表达式就是用逗号隔开的一串表达式,其本质也是整个逗号表达式是一个表达式,其值为最后一个表达式的值,例如:
a = (1+2, 7-5, 8*2, 14/2) ===> a = 7
那么有什么用处呢?还是给大家举个例子:
a = get_val();
count_val(a);
while (a > 0)
{
//业务处理
a = get_val();
count_val(a);
}
//它就等价于
while(a=get_val(), count_val(a), a>0)
{
//业务处理
}
可能大家看不懂,我稍微讲两句小伙伴们就懂了,其实逗号表达式应用之一就是这种类似于dowhile循环句中,就是先进行一些操作A得到一个值作为条件,然后执行判这个值(或含这个值得表达式)的操作B,决定是否执行操作C,如果执行,还要继续进行操作A,进行判断B,执行操作C,直到不满足判断B。例如下代码,计算1到100的奇数偶数和:
int main()
{
//b=-1是为了从1加起,因为先+=2在计算
//********************************************
int a = 0, b = -1, sum1 = 0, sum2 = 0;
while (a+=2, b+=2, a<101)
{
sum1 += a;
sum2 += b;
}
//********************************************
printf("奇数和为%d,偶数和为%dn", sum2, sum1);
return 0;
}
//两个星星框内的代码等价
int main()
{
int a = 0, b = -1, sum1 = 0, sum2 = 0;
//********************************************
a+=2;
b+=2;
while (a < 101)
{
sum1 += a;
sum2 += b;
a+=2;
b+=2;
}
//********************************************
printf("奇数和为%d,偶数和为%dn", sum2, sum1);
return 0;
}
小总结:三目操作符和逗号表达式有着相同的特点,那就是简洁,可以对代码进行优化,减少代码量,使得代码更简洁清楚。凡事有利有弊,缺点就是可读性差,如果大篇幅多次使用这种形式的代码,会导致不容易被看懂,当然,如果大家对这两个东西理解的比较好,勤写注释文档,可以减轻其弊端对你的影响,使你的代码更简洁。
3.下标引用操作符“[]”和函数调用操作符“()”
这两个比较类似,然后也比较简单,放在一起说一下,这个“[]”是针对数组的一个操作符,“()”是针对函数的一个操作符。例如下代码:
//下标引用和函数调用
//此处的“()”不叫函数调用操作符
int get_max(int a, int b)
{
return a>b? a : b;
}
int main()
{
//创建数组,不叫下标引用操作符
int arr[10] = {0};
//下标引用操作符,调用数组某个元素
arr[2] = 5;
//函数调用操作符“()”,内含参数; 下标引用操作符“[]”,调用数组某个元素
int max = get_max(arr[0], arr[2]);
printf("%d和%d相比,大数是%dn", arr[0], arr[2], max);
return 0;
}
//小结:这两个操作符相对特殊,且比较类似,在创建时使用的“[]”和“()”都不叫操作符
//在使用调用时才是操作符,它们的操作数也较为类似,是数组名(函数名)以及括号内的元素
//不同的是“()”的操作数不固定,至少有1个,也就是函数名,上不封顶,看函数定义了多少
//“[]”固定操作数为两个,数组名和下标值
4. 成员访问操作符:点操作符“.”和箭头操作符“->”
好了,难度提升。关于这两个操作符的名字我查了查,各有各的叫法,好像没什么官方化的名字,这里都是我个人的叫法。
其实也不是难度提升,就是这里要用一个我以前没讲过的东西——结构体。之所以这两个成员访问操作符就是为结构体服务的,那么什么事结构体呢?
所谓结构体,就是一种模型,类似于我们盖房子,制造汽车的那个图纸。结构体定制一个规范,属于这个结构体类型的都有结构体中的属性。其实现和使用颇有一种Java面向对象的感觉,我甚至认为Java起源于此(当然纯属个人瞎想)。
在C语言中,结构体定义新的数据类型,也就是我们可以把结构体看做一种自定义数据类型,就像我们的int,char一样,只不过后者是官方定义,且定义的内容只有一种元素,而结构体是自定义的可以有很多元素,直接简单的给大家一个例子:
//定义一个学生的“数据类型”:“struct Stu”
struct Stu
{
//元素包括姓名,年龄,学号
char name[20];
int age;
char id[20];
};
int main()
{
//初始化一个“学生”s1
//这里struct Stu s1就像我们平时写的int a
//struct Stu就是int,s1就是a
struct Stu s1 = {"张三", 18, "20220626"};
return 0;
}
应该是比较容易理解的哈,那么就说一下这两个操作符。这两个操作符是干嘛用的呢,就是为了使用我们用结构体定义的个体。例子:
struct Stu s1 = {"张三", 18, "20220626"};
printf("%sn", s1.name);
printf("%dn", s1.age);
然后接着讲“->”操作符。这两个操作符作用是一样的,但是操作数不一样,顺便说一下两个都是双目操作符。对于点操作符来说,使用格式为:“结构体.成员名”,而箭头操作符格式为:“结构体指针->成员名”。箭头操作符使用例如下代码(当然作为指针变量,解引用操作符“*”用起来肯定是没问题的):
struct Stu* p = &s1;
printf("%sn", (*p).name);
printf("%dn", (*p).age);
printf("%sn", p->name);
printf("%dn", p->age);
说个有意思的,我们可以看到当打出成员访问操作符时,就会出现所有元素供我们选择,说实话跟面向对象用法不能说很像吧,可以说一模一样。
OK,成员访问操作符就说这么多,他们作用效果是完全一样的 ,只是操作数不同:
5.小结
操作符的讲解到这里基本就结束啦,历时数月之久(偷懒致歉),4篇博文,1万多字,终于是把操作符尽可能详细的讲给大家了。不知道大家收获如何,相信大家应该是收获满满吧,在这里提醒大家,像操作符和数据结构这种地基中的地基知识,大家一定要不厌其烦的反复看反复记,要让它深深印在脑海中,会让大家以后无论是学习还是工作中效率加快,好处多多。
下期内容呢还是给大家出一个特别篇,本期内容到这里就完美收官了,如果觉得这篇文章对您有帮助欢迎点赞转发评论区交流,关注小白阿g,让小白不再白学,亲爱的小伙伴们下期见。



