目录
●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!
博文内容:
深刻认识C语言重点操作符
本讲将会教你灵活使用符号,比如使用加减符和异或完成不创建第三方变量交换两个变量值;用逻辑运算符实现if语句的功能
★博文转载请注明出处。
1.注释符号
1.1 基本注释注意事项
// : 单行注释
/* */ : 多行注释(块注释)
大家需要注意的是:注释被替换,本质是替换成空格
大家可以下去测试一下in/* …… */t i ;的执行结果,就能够明白注释的本质了
如果在“”里面加注释,注释不会被替换成空格,只会被当成字符串常量保存起来
C语言风格的注释是不支持嵌套的,且/*总是与离它最近的*/匹配
int main()
{
/*
/*printf("hello world");
printf("hello world");*/
*/
} /*总是与离它最近的*/匹配
1.2 y = x/*p
y = x/*p,这是表示 x 除以 p 指向的内存里的值,把结果赋值为 y?我们可以在编译器
上测试一下,编译器会提示出错。
实际上,编译器把/*当作是一段注释的开始,把/*后面的内容都当作注释内容,直到出现*/为止。这个表达式其实只是表示把 x 的值赋给 y, /*后面的内容都当作注释。但是,由于没有找到*/,所以提示出错
我们可以把代码改一下:
y = x/ *p
或者
y = x/(*p)
这样的话,表达式的意思就是 x 除以 p 指向的内存里的值,把结果赋值为 y 了。
也就是说只要斜杠(/)和星号(*)之间没有空格,都会被当作注释的开始。
1.3 关于注释的规则
来自《C语言深度剖析》
2.接续符和转义符
2.1 接续符 — 续行功能
C 语言里以反斜杠( \)表示断行。编译器会将反斜杠剔除掉,跟在反斜杠后面的字符自动接续到前一行。但是注意:反斜杠之后不能有空格,反斜杠的下一行之前也不能有空格。
2.2 转义字符
转义的本质:字面转特殊,特殊转字面
常用的转义字符及其含义:
\n \t \v \b \r \f \\ \' \a \ddd \xhh | 回车换行 横向跳到下一制表位置 竖向跳格 退格 回车 走纸换页 反斜扛符"\" 单引号符 鸣铃 1~3 位八进制数所代表的字符 1~2 位十六进制数所代表的字符 |
广义地讲, C 语言字符集中的任何一个字符均可用转义字符来表示。表中的\ddd 和\xhh正是为此而提出的。 ddd 和 hh 分别为八进制和十六进制的 ASCII 代码。如\102 表示字母"B",\134 表示反斜线, \X0A 表示换行等
3.单引号和双引号
3.1 基本概念
单引号里的是字符,双引号里的是字符串
C99标准的规定,'a'叫做整型字符常量,被看成是int型(占四个字节大小空间)
3. 2 特殊情况
#include<stdio.h>
int main()
{
printf("%d\n", sizeof('')); //编译器报错
printf("%d\n", sizeof("")); //空串大小是多少 —— 1
return 0;
}
3.3 为何计算机需要字符
计算机本质只认识二进制,那么计算机为何需要字符呢?直接全部二进制它不香吗?
因为计算机是为了解决人的问题,可是,人怎么知道计算机解决了人的问题??你输出二进制结果,人能直接看懂吗?
所以,为何计算机需要需要字符,本质是为了让人能看懂。
那为什么又是英文的呢?中文不香吗?
最早的计算机是美国人发明的,他们的语言是英语,大家想想,英语,不就是26个英文字母+一大堆标点符号组成的嘛。另外,计算机刚刚开始发明,人美国人只要能解决他们的问题就行,所以就有了现在的简单字符
计算机只认识二进制,而人只认识字符。所以,一定要有一套规则,用来进行二进制和字符的转化,这个就叫做ASCII码表
来自度娘
4.逻辑运算符
4.1 &&
&&:逻辑与,级联两个(多个)逻辑表达式,必须同时为真,结果才为真。
注意:与&(按位与)是不同的概念,千万不要弄混了。
请看下面的代码演示
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
if ((++i < 0) && (++j > 0)){
printf("enter if!\n");
}
printf("%d, %d\n", i, j); //1, 1
return 0;
}
上面的++i 和++j 是前置++,先计算后使用,so,if 后面的括号里的表达式计算结果应为假,跳过f语句的代码块,直接来到最后的打印i,j。根据这一连串的操作不难看出:&&就相当于电路串联,符号两边的表达式必须都进行判断。
4.2 ||
|| :逻辑或,级联两个(多个)逻辑表达式,必须至少一个为真,结果才为真
注意:与|(按位或)是不同的概念
请看下面的代码演示
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
if ((++i > 0) || (++j > 0)){
printf("enter if!\n");
}
printf("%d, %d\n", i, j); // 1, 0
return 0;
}
程序具体的解释可以类比&&的,我们直接看打印结果:1 ,0
可能有人就会有疑问:为什么这里结果是1和0,而不是1和1呢?显然,根据 || 的定义,在前一个表达式成立之后,|| 后一个表达式就不会执行;反之,如果前一个不成立,那么就判断下一个表达式的值,类似于电路并联。
4.3 短路
看过上面两个逻辑操作符之后,大家可以发现不管是逻辑与还是逻辑或,都是从左到右执行的,只有这样才能出现我们的短路情况。
上面的一个条件不满足,已经不需要在看后续的条件的情况,就叫做短路
我们可以根据短路来自己“造”一个if语句,来实现if判断执行功能
#include <stdio.h>
#pragma warning(disable:4996) //VS中scanf函数告警,特殊处理安全问题的方法
int show()
{
printf("you can see me!\n");
return 1;
}
int main()
{
int a = 0;
scanf("%d", &a);
a == 10 && show(); //相当于if语句
a == 10 || show(); //类似if not \
前面条件不成立才执行后面的表达式
return 0;
}
关于代码中提到的函数安全问题解决方法,大家可以参考我的另一篇博客,那里有此类问题的分析以及详解。https://mp.csdn.net/mp_blog/creation/editor/123374366https://mp.csdn.net/mp_blog/creation/editor/123374366
当&&前面的条件成立时,执行&&后面的代码,如果不成立,就不执行后面的条件。
当 || 前面条件不成立,执行后面的条件,如果成立,不执行后面的条件。
5.位运算符
5.1 按位
按位指的是逐比特位进行操作
| (按位或):当对等的比特位有一个为1,那么最终结果就为1,
& (按位与):当对等比特位有一个比特位为0,那么最终的结果就不为1了,必须两个同时为1,结果才为1(这里的1,0是数值)
^(按位异或) : 对等的比特位相异为1,相同为0
~(按位反):包括符号位在内,直接进行比特位翻转(1转为0,0转为1)
位运算一定要转化成二进制之后进行操作
5.2好玩的题目
运算规则
任何数据和0进行异或结果都是它本身
异或支持交换律 和结合律
5.3 交换数据时的加减法规则
这种算法只能够用于较小数字的运算,一旦数字过大,加完之后超过了int 所能存储的最大空间·,那么就有可能会出现溢出现象,导致计算结果出错。
5.4 关于溢出
站在二进制的角度,思考一下为什么会出现溢出问题?
比特位太多,加法运算可能产生进位
溢出:比特位增多是在CPU内部进行增多的
截断:是将数据写回内存时,内存的空间不足才导致截断的
5.6 通过异或解决整数交换问题
记住先不进行计算每一步的异或结果,后面直接根据前面的两条规则得出答案
溢出的本质是进位,而这里没有发生加法,就不会产生进位,更不会出现溢出问题