12. C语言 -- 拾遗

本博客主要内容为 “小甲鱼” 视频课程《带你学C带你飞》【第一季】 学习笔记,文章的主题内容均来自该课程,在这里仅作学习交流。在文章中可能出现一些错误或者不准确的地方,如发现请积极指出,十分感谢。
也欢迎大家一起讨论交流,如果你觉得这篇文章对你有所帮助,记得评论、点赞哦 ~(。・∀・)ノ゙

1. 赋值运算符

  赋值运算符是 C 语言中用得最多的一个运算符,我们每天都在用它。因此它的设计简便与否直接影响到了 C 语言的开发效率。语法很简单,就是将右边的值放到左边的变量里边,因为它的执行方向是自右向左,比如

int a;
a = 5;

需要注意的是赋值运算符的左边必须是一个 lvalue,变量名就是 lvalue,但常数就不是了,所以你把 5 写在赋值号的左边就会出错,比如说执行

5 = a;

编译系统会提示类似于“error: lvalue required as left operand of assignment”的错误。很多人在这里将 lvalue 理解为左值,即“left value of the赋值运算符”,对应的将 rvalue 理解为右值。但是这是一种不完全正确的理解方式。那到底什么是 lvalue 什么是 rvalue 呢?

1.1 lvalue 与 rvalue

  将lvaluervalue 理解为左值和右值实际上理解并不全面,并且常常容易犯思想上的错误。一种更合理的解释是将 lvalue 理解为 locator value(特定位置的值),rvalue 则应该是 value of an expression(表达式的值)。比如尝试执行下面这段代码

#include 

int main()
{
        int a = 5;
        ++(a++);
        return 0;
}

同样会得到报错,如下所示
在这里插入图片描述

在这里如果你认为 lvalue 只是赋值运算符左边那个值,那这个错误提示就无法理解了。因为首先看括号内的内容 (a++),他肯定是没有问题的,那么问题肯定是出在外面的那一层 ++ 上,但是这个时候明显是问题处在 ++ 的右边而不是左边啊,应该报 rvalue 的错误,而不是 lvalue 的错误啊。

  但是如果你知道 lvalue 是用于识别或定位存储位置的标识符,那么就好解释了:(a++) 是先将变量 a 的值(5)做为整个表达式的值返回,再将 a 自增 1(类似于 a = a + 1),所以++(a++); 等价于 ++(5), a = a + 1;,5 是一个常量,当然不能 5 = 5 + 1 了(即++5)~

  所以C 语言的术语 lvalue 指用于识别或定位一个存储位置的标识符。(注意:左值同时还必须是可改变的);rvalue 你可以理解为 readable value,即任何可读取的值都被认为是右值(非左值)。

2. 复合的赋值运算符

  由于赋值运算符的使用度非常高,所以 C 语言的作者也想出了如下的一些编辑的方案。
12. C语言 -- 拾遗_第1张图片

3. 自增自减运算符

  当我们需要对一个变量加一或减一并赋值给自己的时候,我们可以写成 i++i—++i--i 的形式。它们也被称为增量减量运算符,或 ++-- 运算符。另外,自增、自减运算符只能作用于变量,而不能作用于常量或表示。

  i++++i 的区别在于:

  (1) i++ 是先使用变量 i 中保存的值, = 再对自身进行 ++ 运算;
  (2) ++i 是先对自身进行 ++ 运算,再使用变量 i 的值(这时候变量i的值已经加 1 了)。

  其实这两者间的区别很好记忆,谁在前面先执行谁,i 在前面先使用变量 i 中保存的值,++ 在前面先对自身进行 ++ 运算,比如说如下的这段代码

#include 

int main()
{
	int i = 5, j;

	j = ++i;
	printf("i = %d, j = %d\n", i, j);

	i = 5;
	j = i++;
	printf("i = %d, j = %d\n", i, j);

	return 0;
}

将会输出如下的结果

i = 6, j = 6
i = 6, j = 5

4. 逗号运算符

  逗号表达式的语法是

表达式1,表达式2,表达式3,...... ,表达式n

逗号表达式的运算过程为:从左往右逐个计算表达式;逗号表达式作为一个整体,它的值为最后一个表达式(也即表达式n)的值。不过,逗号运算符在C语言的所有运算符中,是最没有地位的那个。因为连赋值运算符的优先级都比逗号运算符要高,所以

a = 3, 5

相当于

a = 3;
5;

  需要注意的是,在 C 语言中看到的逗号,不一定就都是逗号运算符,因为在有些地方,逗号仅仅是被用作分隔符而已。比如

int a, b, c; 
scanf("%d%d%d", &a, &b, &c);

这里逗号都是作为分隔符使用,而不是运算符。

5. 条件运算符

  有一个操作数的运算符称为单目运算符,有两个两个操作数称为双目运算符,然而 C 语言还有唯一的一个三目运算符,它的作用是提供一种简写的方式来表示 if-else 语句,其语法如下

exp1 ? exp2 : exp3;

exp1 是条件表达式,如果结果为真,返回 exp2,如果为假,返回 exp3,所以下面的代码

if (a > b){
    max = a;
}
else{
    max = b;
}

等价于

max = a > b ? a : b;

6. goto 语句

   goto 语句可以说是一个历史遗留,因为早的编程语言都留有很多汇编语言的痕迹,比如 goto 语句就是其中之一。goto 语句的作用就是直接跳转到指定标签的位置,其语法为:

goto 标签;

其中标签需要被定位于某个语句的前边,比如:

#include 

int main()
{
        int i = 5;

        while (i++){
                if (i > 10){
                        goto Label;
                }
        }

Label:  printf("Here, i = %d\n", i);

        return 0;
}

可以看到 while 本身是一个死循环,但是当执行到 i=11 的时候,会通过 goto 语句跳转到 Label 所对应的位置,执行打印输出。

  开发中要尽量避免使用 goto 语句。其实就连 C 语言的作者也觉得 goto 语句非常容易被滥用,并且建议一定要谨慎使用,甚至根本不用它。但在一种情况下使用 goto 语句是情有可原的,那就是当面临要跳出多层循环的时候,使用 goto 语句要比多个 break 语句好使。

7. 注释

  C 语言的注释有两种方式,一种是大家常用的,将注释写在两个连续斜杠的后边:

// 我是是注释,编译器不会注意我的

这样每一行注释的开头都需要有两个斜杠,有时候你可能需要写多行注释,那你可以使用 /* 注释的内容 */ 来实现:

/* 这是一个跨越多行的注释
   对!这是注释~
   对!!我也是
   对!!!我也是
   对!!!!还有我 */

  初学的程序员有的时候会滥用注释,具体来讲就是在每一段代码的后面都会加上一段注释。在实际编程中,我们需要在函数的下面使用一个跨多行的注释,主要用于介绍函数的功能,参数的含义和返回值;再有就是对于变量的命名及适用范围进行说明;最后就是在自己觉得需要地方加了……嗯,不要到处加啊 [\手动捂脸]。

参考

[1] “小甲鱼” 视频课程《带你学C带你飞》【第一季】P16

欢迎大家关注我的知乎号(左侧)和经常投稿的微信公众号(右侧)
12. C语言 -- 拾遗_第2张图片

你可能感兴趣的:(C,从零入门C语言!!!)