ToB企服应用市场:ToB评测及商务社交产业平台

标题: 对C语言符号的一些冷门知识运用的剖析和总结 [打印本页]

作者: 熊熊出没    时间: 2024-5-19 03:55
标题: 对C语言符号的一些冷门知识运用的剖析和总结
符号


目次

注释

C语言风格的注释: /* 这是注释 */
C++风格的注释: //这是注释
奇怪的注释
  1. int main()
  2. {
  3. int /* */ i;                    //1.正确
  4. char *s = "abcdefgh //hijklmn"; //2.正确://是字符串的一部分
  5. //Is it a\
  6. valid comment?                  //3.正确  注释可以通过续行符续行
  7. in/* */t j;                     //4.报错
  8. system("pause");
  9. return 0;
  10. }
复制代码
gcc4.8.5的语法检查:

为什么4是错的?  看预编译后的结果:
实行预编译命令:gcc -E test.c -o test.i

(发现预处理阶段gcc并没有报错,说明问题是出在编译后的)

可以发现 第9行 int中间多了空格,说明注释在预编译可能会被转化成空格.
而第5行的int i中间只有一个空格,说明注释是直接被删除或归并成一个空格.
结论:注释在预编译后会替换成空格,具体替换方式由编译器决定
C风格的注释无法嵌套

预编译:

可以发现预编译后上面两个\*没有了,下面还有一个*\.
原因: C语言把遇到的第一个/*之后的数据都当作注释,直到遇到第一个/*,因此嵌套在中间的/*不会再被检查出来.且在预处理阶段会删除掉这些注释.所以嵌套的注释会留下一个*.
C风格注释采用的是就近原则.如果要能嵌套,就得使用就远原则才足以容纳多个嵌套
至于为什么不选择像代码块这样的匹配规则,可能就是汗青遗留问题了,有知道的朋友可以分享在评论区.
一些特殊的注释



解决方法:
1.在/和*后加上一个空格  int b = 20/ *p
2.用圆括号把(*)括起来int b = 20/(*p) ,推荐这种方式,更为直观
注释的规则建议

反斜杠'\'

反斜杠有续行的作用,但要注意续行后不能添加空格

如图,在续行符前加多个空格没有影响:

但续行符后不能加空格

回车也能起到换行的作用,那续行符的意义在哪?

续航符本身就有自描述性.这是续行符最大的意义,就是要明白告诉别人这里是换行的,没有二义性.如果使用回车,别人在阅读的时候有可能需要思索是不是故意换行的或者是不是不小心误敲了.
反斜杠的转义功能

转义,即对某些字符进行反斜杠,可以使之拥有超过本身的功能,
转义有两种,一种是诸如\n,\t这样的转义字符,转义后具有本身字面值之外的特殊功能;另一种诸如\",\\这种,本身字面值没有意义,而是其他功能,转义后具有字面值的意义.
转义的功能简单描述就是 (a. 字面转特殊  b. 特殊转字面)
单引号和双引号

基本概念:单引号内的是字符,双引号的是字符串
字面值,字符串,字符,字符变量的大小

sizeof分别盘算大小:

为什么sizeof('1')的大小是4 ?

C99标准的规定,'a'这种单引号引起来的字符叫做整型字符常量(integer character constant),会被编译器当作整型.因此大小是4个字节
(注意:在C++中字符常量大小为1,不同平台/语言解释是不一样的.)
char类型一直在发生截断.

char类型基本上都是接收整型字符常量,而char类型只占一个字节大小,因此只能保留整型的一个字节(首字节),即截断.
不允许定义空字符常量

单引号内至少要有一个字面值

单引号内一样平常是一个字符,还可以有多个字符

如下图,可以发现是没有警告的.

打印结果:

但是最多4个字符,多了会告警

为什么能这样用呢? 也是上文所说的,字符常量被C语言当作整型来看待,分配了4个字节.
一个字符字面值就占一个字节,4个字符就刚好占了4个字节,整型分配的空间能够满足.
而char类型又是截断了整型的低地址字节位,因此只会输出最后一个字符字面值(小端).
短路

逻辑与&&和逻辑或||的左边条件不满足,则不需要再看后续条件的情况,就叫做短路.
  1. int show()
  2. {
  3.     printf("aaaaaaa");
  4.     return 1;
  5. }
  6. int main()
  7. {
  8.    int flag = 0;
  9.    scanf("%d",&flag);
  10.    flag && show();  //使用短路实现的if语句效果
  11.    //如果表达式左边为假,则表达式右边不再执行,这样的语句就称为短路.
  12.    scanf("%d",&flag);
  13.    flag || show();  //使用短路实现的if not语句
  14.     return 0;
  15. }
复制代码
位运算

位运算和逻辑运算区别

位运算是一位对应一位的对全部位逐一进行运算(逐比特位进行运算).逻辑运算是以盘算表达式的真假为主进行运算.
位运算的几点注意

异或的运算规则

0000 0000 ... 0111
printf("%d\n",4^3); //结果:7
  1. 2. 任何数据和0异或,结果都是它本身
  2. ```C
  3. printf("%d\n",1 ^ 0);  //结果:1
  4. printf("%d\n",6 ^ 0);  //结果:6
  5. printf("%d\n",7 ^ 0);  //结果:7
  6. printf("%d\n",-1 ^ 0); //结果:-1
复制代码
异或的经典问题:两数交换

问题:两个变量int a = 10; int b = 20;再不使用第三个变量的前提下,怎么讲两个数进行交换?
方法一:加减法
  1.     a = a + b;  // ①
  2.     b = a - b;  // ②
  3.     a = a - b;  // ③
复制代码
剖析:
(在盘算机运算中,运算过程可以当作第三个变量,只是这个过程必须赋值才有意义,我们可以盘算出各种组合的值用来匹配和验证)
缺点: 加法可能会有比特位递增,如果发生溢出,则会发生截断,导致数据丢失.所以这种方法仅实用于一定范围的数据
方法二:异或法
  1.     a = a ^ b; //①
  2.     b = a ^ b; //②
  3.     a = a ^ b; //③
  4. 一次记住它: 等号左边是aba,右边全是a^b
复制代码
剖析消消乐)
相对于加减法的长处: 异或不会进位,不会出现比特位递增、溢出的问题
位操纵建议使用宏定义好后使用

[code]// 0|0 = 0 ; 0|1 = 1  //  规律:任何数或0结果都是它本身      //用途:// 1|0 = 1 ; 1|1 = 1  //  规律:任何数或1,结果都是被设置为1  //用途:特定 比特位 置1// 组合用途:让特定比特位置1,其他位不变// 0&0 = 0 ; 0&1 = 0; //  规律:任何书与0,结果都是被设置成0  //用途:特定比特位置0// 1&0 = 0 ; 1&1 = 1; //  规律:任何书与1,结果都是它本身     //用途:获取特定比特位的值// 组合用途:没有干扰地获取特定比特位的值//一样平常都是用1(000...1)比力方便,通过移动1的位置,加上不同的位运算符,能够实现不同的功能.#define SETBIT(x,n)  (x |= (1




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4