C 运算符

在 C 语言中,运算符指的是 “变量” 或 “值” 进行计算操作的符号。运算符用于将一个或几个值进行计算,从而得出所需要的结果。就像我们的数学,也需要加减乘除这些运算符才可以计算结果。不过对于 C 语言来说,我们需要遵循的不是数学那一套玩意,而是计算机语言的一套方法。

C运算符语法

在 C 语言中,常用的运算符有以下 6 种。

  • 算术运算符
  • 自增运算符和自减运算符
  • 赋值运算符
  • 比较运算符
  • 逻辑运算符
  • 条件运算符

C 算术运算符

在 C 语言中,算术运算符一般用于“数学”计算,包括加、减、乘、除等。常用的算术运算符如下表所示。

C 算术运算符
运算符 说明 示例
+ 10 + 5     // 返回 15
10 - 5      // 返回 5
* 10 * 5      // 返回 50
/ 10 / 5      // 返回 2
% 求余 10 % 4     // 返回 2

注意: 在 C 语言中,乘号是星号(*),而不是 ×,除号是斜杠(/),而不是 ÷,所以小伙伴们一定要搞清楚。为什么要这样定义呢?这是因为 C 语言的开发者,是希望尽量使用键盘已有的符号来表示这些运算符。大家好好看看自己的键盘就明白了。

对于算术运算符来说,有以下 2 点需要注意的。

  • 对于加、减、乘、除这 4 种运算,如果两个数都是整型,那么结果也是整型。如果有任意一个数是浮点型,那么结果就是浮点型的。如果一个是 float,另一个是 double,那么结果就是 double(选择精度最高的)。
  • 对于求余运算符,要求两个数都是整型,而不能是其他类型。而对于其他运算符,两个数可以是任意类型。

示例 1:整型的加减乘除

#include <stdio.h>

int main(void)
{
    int a = 20;
    int b = 10;

    int result1 = a + b;    // 加
    int result2 = a - b;    // 减
    int result3 = a * b;    // 乘
    int result4 = a / b;    // 除

    printf("%d\n", result1);
    printf("%d\n", result2);
    printf("%d\n", result3);
    printf("%d", result4);

    return 0;
}

运行结果如下。

30
10
200
2

分析:

printf() 函数输出内容时并不会自动换行,小伙伴们别忘了使用 “\n” 来换行。对于最后一个 printf() 来说,因为后面没有其他输出了,所以一般不需要加上 “\n”。

当然了 printf() 不仅仅可以输出一个 “值”,其实还可以输出一个 “表达式”。对于上面这个例子,它可以等价于下面代码。

#include <stdio.h>

int main(void)
{
    int a = 20;
    int b = 10;

    printf("%d\n", a + b);      // 加
    printf("%d\n", a - b);      // 减
    printf("%d\n", a * b);      // 乘
    printf("%d", a / b);        // 除

    return 0;
}

示例 2:浮点型的加减乘除

#include <stdio.h>

int main(void)
{
    int a = 20;
    float b = 10.0;

    printf("%f\n", a + b);      // 加
    printf("%f\n", a - b);      // 减
    printf("%f\n", a * b);      // 乘
    printf("%f", a / b);        // 除

    return 0;
}

运行结果如下。

30.000000
10.000000
200.000000
2.000000

分析:

对于加、减、乘、除这 4 种运算,只要有一个数是浮点型,那么结果就是浮点型的。对于是 float 还是 double,这个根据实际类型来判断。

示例 3:求余运算符

#include <stdio.h>

int main(void)
{
    int a = 24;
    int b = 10;

    printf("%d", a % b);
    return 0;
}

运行结果如下。

4

分析:

求余运算的结果等于两个整数相除后的余数,所以 24 % 10 的结果是 4。另外,进行求余运算的两个数必须是整数。

示例 4:除号运算符(无法整除)

#include <stdio.h>

int main(void)
{
    int a = 5 / 2;
    int b = 8 / 10;

    printf("%d\n", a);
    printf("%d", b);
    return 0;
}

运行结果如下。

2
0

分析:

如果除号两边都是整型,那么它的结果也是一个整型。实际上,对于加减乘除来说,只要两个数都是整型,那么结果也一定是一个整型。

如果发生无法整除,此时结果是怎样的呢?你可以按照数学方式处理,最后得到一个带小数的值,然后直接把小数部分去除就可以了。比如 5 / 2 按照数学方式,结果是 2.5,然后我们去除小数部分就是 2 了。

C 自增运算符和自减运算符

C 语言中的自增自减运算符,指的是在 “原值” 的基础上加上或减去 1。自增自减运算符的 “坑” 比较多,初学者要重点掌握。

语法:

++变量名;     // 前缀形式
变量名++;     // 后缀形式

--变量名;     // 前缀形式
变量名--;     // 后缀形式

说明:

自增和自减运算符可以分为前缀形式和后缀形式。对于前缀形式来说,它是先进行自增或自减运算,然后再使用变量的值。而对于后缀形式来说,它是先使用变量的值,然后再进行自增或自减运算。

1. C 自增运算符

在 C 语言中,自增运算符是 “++”(双加号)。所谓的自增,指的是在 “原来的值” 的基础上再加上 1。对于自增运算符来说,它可以分为 2 种情况:① ++n;② n++。

(1)++n

“++n” 指的是在“使用 n 之前”,先让 n 的值加上 1。

示例 5:使用 ++n

#include <stdio.h>

int main(void)
{
    int a = 1;
    int b = ++a;

    printf("%d\n", a);
    printf("%d", b);
    return 0;
}

运行结果如下。

2
2

分析:

int a = 1;
int b = ++a;

int b = ++a; 表示在使用 a 之前(即将 a 赋值给 b 之前),先让 a 进行自增操作。对于这个例子来说,上面代码等价于下面代码。

int a = 1;
a = a + 1;      // a = 1 + 1,a 的值变成 2
int b = a;      // 由于上面 a 的值变为 2了,所以 b 的值也是 2

(2)n++

n++ 指的是在 “使用 n 之后”,再让 n 的值加上 1。

示例 6:使用 n++

#include <stdio.h>

int main(void)
{
    int a = 1;
    int b = a++;

    printf("%d\n", a);
    printf("%d", b);
    return 0;
}

运行结果如下。

2
1

分析:

int a = 1;
int b = a++;

int b = a++; 表示在使用 a 之后(即将 a 赋值给 b 之后),再让 a 进行自增操作(++)。对于这个例子来说,上面代码等价于下面代码。

int a = 1;
int b = a;      // 由于 a 的值为 1,所以 b 的值为 1
a = a + 1;      // 由于上面 a 的值为 1,所以这里 a = 1 + 1,也就是 2

对于b = ++a; 和 b = a++;,小伙伴们一定要严格区分。可以这样简单记忆:如果 ++ 在 a 的左边(前面),就是先使用 a = a + 1(即自增),而后使用 b = a。如果 ++ 在 a 的右边(后面),就是后使用 a = a + 1,而先使用 b = a。a = a + 1 的使用位置,是根据 ++ 的使用位置来决定的。

2. C 自减运算符

在 C 语言中,自减运算符是 “++”(双减号)。所谓的自减,指的是在 “原来的值” 的基础上再减去 1。对于自减运算符来说,它也可以分为 2 种情况:① --n;② n--。

(1)--n

“--n” 指的是在 “使用 n 之前”,先让 n 的值减去 1。

示例 7:使用 --n

#include <stdio.h>

int main(void)
{
    int a = 1;
    int b = --a;

    printf("%d\n", a);
    printf("%d", b);
    return 0;
}

运行结果如下。

0
0

分析:

int a = 1;
int b = --a;

int b = --a; 表示在使用 a 之前(即将 a 赋值给 b 之前),先让 a 进行自减操作(--)。对于这个例子来说,上面代码等价于下面代码。

int a = 1;
a = a - 1;      // a = 1-1,a 的值变成 0
int b = a;      // 由于上面 a 的值变为 0 了,所以 b 的值也是 0

(2)n--

n-- 指的是在 “使用 n 之后”,再让 n 的值减去 1。

示例 8:使用 n--

#include <stdio.h>

int main(void)
{
    int a = 1;
    int b = a--;

    printf("%d\n", a);
    printf("%d", b);
    return 0;
}

运行结果如下。

0
1

分析:

int a = 1;
int b = a--;

int b = a--; 表示在使用 a 之后(即将 a 赋值给 b 之后),再让 a 进行自减操作(--)。对于这个例子来说,上面代码等价于下面代码。

int a = 1;
int b = a;      // 由于 a 的值为 1,所以 b 的值为 1
a = a - 1;      // 由于上面 a 的值为 1,所以这里 a = 1 + 1,也就是 0

自增(++)和自减(--)的运算规则是一样的,小伙伴们对比理解一下,非常的简单。

C 赋值运算符

在 C 语言中,赋值运算符用于将右边表达式的值保存到左边的变量中去。常用的赋值运算符有 5 种,如下表所示。

C 赋值运算符
运算符 示例
= a = 2025
+= a += b 等价于 a = a + b
-= a -= b 等价于 a = a - b
*= a *= b 等价于 a = a * b
/= a /= b 等价于 a = a / b

上面只是列举了常用的赋值运算符,对于不常用的就不列出来了,这个也是避免增加小伙伴们的记忆负担。在本教程中,我们都是采用这种方式:不常用的不会啰嗦,重要的则会反复强调。

+=、-=、*=、/= 这几个运算符其实就是为了简化代码而出现的,比如 int a += b; 其实就是 int a = a + b; 的简化形式。大多数有经验的开发人员都喜欢用这种简写形式。对于初学者来说,我们还是要熟悉一下这种写法,免得看不懂别人的代码。

示例 9:使用赋值运算符

#include <stdio.h>

int main(void)
{
    int a = 10;
    int b = 5;

    a += b;
    b += a;
    printf("%d\n", a);
    printf("%d", b);

    return 0;
}

运行结果如下。

15
20

分析:

首先我们初始化了变量 a 的值为 10,变量 b 的值为 5。当执行 a += b; 后,此时 a 的值为 15(10 + 5),b 的值没有变化,依旧是 5。

由于程序是从上而下地执行的,当执行 b += a; 时,由于之前 a 的值已经变为 15 了,因此执行后,a 的值为 15,b 的值为 20(15 + 5)。

这里小伙伴们要知道一点:a 和 b 都是变量,它们的值是会随着程序的执行而变化的。

C 比较运算符

在C语言中,比较运算符又叫做 “关系运算符”。比较运算符用于将运算符两边的值或表达式进行比较。比较运算符的运算结果是一个逻辑值,也就是 “真” 或 “假”。在 C 语言中,“真” 用 “1” 表示,“假” 用 “0” 表示。也就是说,如果比较结果是对的,则返回 “1”;如果比较结果是错的,则返回 “0”。

在 C 语言中,常用的比较运算符如下表所示。

C 比较运算符
运算符 说明 示例
> 大于 2 > 1        // 返回 1
< 小于 2 < 1        // 返回 0
>= 大于等于 2 >= 2     // 返回 1
<= 小于等于 2 <= 2     // 返回 1
== 等于 1 == 2     // 返回 0
!= 不等于 1 != 2      // 返回 1

注意: “=”(一个等号)是赋值运算符,用于将右边的值赋值给左边的变量。“==”(两个等号)是比较运算符,用于比较左右两边的值是否相等。如果想要比较两个值是否相等,写成 a = b 是错误的,正确写法应该是 a == b。

示例 10:使用比较运算符

#include <stdio.h>

int main(void)
{
    int a = 10;
    int b = 5;

    int result1 = (a > b);
    int result2 = (a == b);
    int result3 = (a != b);

    printf("%d\n", result1);
    printf("%d\n", result2);
    printf("%d", result3);

    return 0;
}

运行结果如下。

1
0
1

分析:

对于一条语句,都是先运算右边,然后再将右边结果赋值给左边变量。另外,由于关系运算符返回的结果是一个整数,所以我们用于保存结果的变量必须是一个 int 类型。

虽然在 C 语言中,运算符会遵循一定的优先级,但是为了可读性,我们更推荐加上必要的小括号,以便让代码可读性更高。

// 不推荐
int result1 = a > b;
int result2 = a == b;
int result3 = a != b;

// 推荐
int result1 = (a > b);
int result2 = (a == b);
int result3 = (a != b);

提示: 对于运算符的优先级,另请参阅:C 运算符优先级

逻辑运算符

在 C 语言中,逻辑运算符用于判断 “真” 或 “假”,它常常和比较运算符结合在一起使用。常见逻辑运算符有 3 种,如下表所示。

C 逻辑运算符
运算符 说明
&& “与” 运算
|| “或” 运算
! “非” 运算

1. “与” 运算

在 C 语言中,与运算用 “&&” 表示。如果 “&&” 两边的值都为真,则结果返回真;如果有一个为假或者两个都为假,则结果返回假。

真 && 真 → 真
真 && 假 → 假
假 && 真 → 假
假 && 假 → 假

示例 11:使用与运算

#include <stdio.h>

int main(void)
{
    int a = 10;
    int b = 5;
    int c = 5;

    int result = (a < b) && (b == c);
    printf("%d", result);

    return 0;
}

运行结果如下。

0

分析:

int result = (a < b) && (b == c); 等价于 int result = (10 < 5) && (5 == 5);,由于 (10 < 5) 返回结果为 0 而 (5 == 5) 返回结果为 1,所以 int result = (a < b) && (b == c); 最终等价于int result = 0 && 1;。根据与运算的规则,result 最终的值为 0。

2. “或” 运算

在 C 语言中,或运算用 “||” 表示。如果 “||” 两边的值都为假,则结果返回假;如果有一个为真或者两个都为真,则结果返回真。

真 || 真 → 真
真 || 假 → 真
假 || 真 → 真
假 || 假 → 假

示例 12:使用或运算

#include <stdio.h>

int main(void)
{
    int a = 10;
    int b = 5;
    int c = 5;

    int result = (a < b) || (b == c);
    printf("%d", result);

    return 0;
}

运行结果如下。

1

分析:

int result = (a < b ) || (b == c); 等价于 int result = (10 < 5) || (5 == 5);,由于 (10 < 5) 返回结果为 0 而 (5 == 5) 返回结果为 1,所以 int result = (a<b) || (b == c); 最终等价于 int result = 0 || 1;。根据或运算的规则,result 最终的值为 1。

3. “非” 运算

在 C 语言中,非运算用 “!”(英文叹号)表示。非运算跟与运算、或运算不太一样,非运算操作的对象只有一个。当 “!” 右边的值为真时,最终结果为假;当 “!” 右边的值为假时,最终结果为真。

!真 → 假
!假 → 真

这个其实就是很简单的啦,直接取反就行。这家伙就是专门跟你唱反调的。

示例 13:使用非运算

#include <stdio.h>

int main(void)
{
    int a = 10;
    int b = 5;
    int c = 5;

    int result = !(a < b) && !(b == c);
    printf("%d", result);

    return 0;
}

运行结果如下。

0

分析:

int result = !(a<b) && !(b == c); 等价于 int n = !(10<5) && !(5 == 5);,也就是 int result = !0 && !1;。由于 !0 的值为 1,!1 的值为 0。因此最终等价于 int result = 1 && 0;,也就是 0。

大家可以把上面的 “&&” 改为 “||”,然后看看结果又是怎么样的。小伙伴们也不要被这些看起来复杂的运算吓到了。实际上,再复杂的运算,一步一步来,也是非常简单的。

对于与运算、或运算和非运算,我们可以总结出以下 3 点。

  • 1 的 ! 为 0,0 的 ! 为 1。
  • a && b:a、b 全为 1 时,结果为 1,否则结果为 0。
  • a || b:a、b 全为 0 时,结果为 0,否则结果为 1。

4. 深入逻辑运算符

对于与或非运算,有一个非常重要的结论:如果一个值不等于 0,那么它本质上就是相当于 1(真)

示例 14:值为真的情况

#include <stdio.h>

int main(void)
{
    printf("%d\n", 2025 && 84);
    printf("%d\n", 3.15 && 12);
    printf("%d\n", 'A' && 10);
    return 0;
}

运行结果如下。

1
1
1

分析:

2025 && 84 本质上等于 1 && 1,3.15 && 12 本质上等于 1 && 1,'A' && 10 本质上等于 1 && 1。总而言之,只要值不等于 0,那么在与或非运算中,这个值就相当于 1。

示例 15:值为假的情况

#include <stdio.h>

int main(void)
{
    printf("%d\n", 2025 && 0);
    printf("%d", 3.15 && 0);
    printf("%d\n", 'A' && 0);
    return 0;
}

运行结果如下。

0
0
0

分析:

2025 && 0 本质上等于 1 && 0,3.15 && 0 本质上等于 1 && 0,'A' && 0 本质上等于 1&&0。小伙伴们可以自行测试一下 “||” 和 “!” 这两个,非常简单。

C 条件运算符

除了上面这些常用的运算符,C 语言还为我们提供了一种特殊的运算符:条件运算符。条件运算符,也叫 “三元运算符” 或 “三目运算符”。在 C 语言中,条件运算符用 “?” 和 “:” 这两个组合来表示。

语法:

类型 变量名 = 条件 ? 表达式1 : 表达式2;

说明:

当条件为真时,我们选择的是 “表达式 1”。当条件为假时,我们选择的是 “表达式 2”。

条件运算符其实是很简单的,也就是 “二选一”。就好比有两个女生在你面前,也许你都喜欢,但是只能选择其中一个做女朋友,对吧?

示例 16:条件运算符求两数的最大值

#include <stdio.h>

int main(void)
{
    int a = 10;
    int b = 5;

    int result = (a > b) ? a : b;
    printf("%d", result);

    return 0;
}

运行结果如下。

10

分析:

由于条件(10 > 5)返回 “真(1)“,所以最终选择的是 a。也就是说 int result = (a > b) ? a : b; 等价于 int result = a;,所以 result 的值为 10。

C 运算符的常见问题

1. 像 n++、n-- 这种可以使用 n = n+1、n = n-1来代替,为什么还要搞 n++、n-- 这种自增自减运算符出来呢?

在现代编译器优化下,n++ 和 n = n + 1 的执行效率是一样的。我们推荐使用 n++ 的主要原因是:代码更简洁、更易读,且符合 C 语言程序员的编码习惯。

2. 明明有一个 “=” 这一个赋值运算符就够用了,为什么 C 语言还要搞像 +=、-=、*=、/= 那么多的赋值运算符出来呢?

这一点和自增自减运算符是一样的,a += b 和 a = a + b 执行效率是一样的。我们推荐使用 a += b 主要是这种方式更符合 C 语言程序员的编码习惯。

上一篇: C 转义字符

下一篇: C 运算符优先级

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号