首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

扩展分析C语言单双引号、反斜杠与注释

编程知识
2024年09月18日 20:00

目录

注释

C语言风格的注释: /* 这是注释 */
C++风格的注释: //这是注释


奇怪的注释

int main()
{
int /* */ i;                    //1.正确
char *s = "abcdefgh //hijklmn"; //2.正确://是字符串的一部分
//Is it a\
valid comment?                  //3.正确  注释可以通过续行符续行
in/* */t j;                     //4.报错
system("pause");
return 0;
}

gcc4.8.5的语法检查:
1正确的注释.png
为什么4是错的? 看预编译后的结果:
执行预编译命令:gcc -E test.c -o test.i

1gcc编译.png

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

1预编译后的注释
可以发现 第9行 int中间多了空格,说明注释在预编译可能会被转化成空格.

而第5行的int i中间只有一个空格,说明注释是直接被删除或合并成一个空格.

结论:注释在预编译后会替换成空格,具体替换方式由编译器决定


C风格的注释无法嵌套

预编译:

C风格注释不能嵌套.png

可以发现预编译后上面两个\*没有了,下面还有一个*\.

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


一些特殊的注释

  • 宏中间的注释

一些特殊的注释

  • 除号和*号同时使用

bd9dd9d0-ed43-476d-ba9e-4237c15775e7

解决方法:

1.在/和*后加上一个空格 int b = 20/ *p

2.用圆括号把(*)括起来int b = 20/(*p) ,推荐这种方式,更为直观

注释的规则建议

  1. 注释应当准确、易懂,防止有二义性。错误的注释不但无益反而有害。

  2. 边写代码边注释,修改代码的同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释要即使删除。

  3. 注释是对代码的的“提示”,而不是文档。程序中的注释应当简单明了,注释太多了会让人眼花缭乱。

  4. 对于全局数据(全局变量、常量定义等)必须要加注释。

  5. 注释的位置应与被描述的代码相邻,可以与语句在同一行,也可以在上行,但不可以放在下方。同一结构中不同域的注释要对齐。

  6. 当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释,便于阅读。

  7. 注释代码段时应注重“为何做(why) ",而不是怎么做”(how)“
    说明怎么做的注释一般停留在编程语言的层次,而不是为了说明问题。尽力阐述“怎么做”的注释一般没有告诉我们操作的意图,而指明“怎么做”的注释通常是冗余的。

  8. 数值的单位一定要注释。如时、分、秒等单位。

  9. 对变量的范围给出注释,尤其是参数。

  10. 对一系列的数字编号给出注释,尤其在编写底层驱动程序的时候(比如引脚编号)。

  11. 在复杂的函数中,在分支语句、循环语句结束之后需要适当的注释,方便区分各分支或循环体。(很多时候代码写长后,一个屏幕内看不到下面的代码,不知道哪个才是相应代码块匹配的花括号)


反斜杠'\'


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

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

7b2ff3f7-5848-42cc-8a45-24c97b3585f9

但续行符后不能加空格

f8cf3aed-e3ac-4025-9c8d-97ac16dd43dc


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

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


反斜杠的转义功能

转义,即对某些字符进行反斜杠,可以使之拥有超过本身的功能,

转义有两种,一种是诸如\n,\t这样的转义字符,转义后具有本身字面值之外的特殊功能;另一种诸如\",\\这种,本身字面值没有意义,而是其他功能,转义后具有字面值的意义.

转义的功能简单描述就是 (a. 字面转特殊 b. 特殊转字面)


单引号和双引号

基本概念:单引号内的是字符,双引号的是字符串


字面值,字符串,字符,字符变量的大小

sizeof分别计算大小:

f0339503-6593-4f95-b8ef-152f6b55d48b


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

C99标准的规定,'a'这种单引号引起来的字符叫做整型字符常量(integer character constant),会被编译器看成整型.因此大小是4个字节

(注意:在C++中字符常量大小为1,不同平台/语言解释是不一样的.)

char类型一直在发生截断.

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


不允许定义空字符常量

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

a92d0e67-ae21-41a0-bcee-868c14f79dcb


单引号内一般是一个字符,还可以有多个字符

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

819f3b5e-35aa-413b-886b-029ba7f03d29

打印结果:

7d90218a-50d7-46fe-b206-77eba1eb41b9

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

d5e2f2e1-cc45-43b0-b75e-589da65f1711

为什么能这样用呢? 也是上文所说的,字符常量被C语言当作整型来看待,分配了4个字节.

一个字符字面值就占一个字节,4个字符就刚好占了4个字节,整型分配的空间能够满足.

而char类型又是截断了整型的低地址字节位,因此只会输出最后一个字符字面值(小端).


From:https://www.cnblogs.com/DSCL-ing/p/18414570
本文地址: http://shuzixingkong.net/article/2111
0评论
提交 加载更多评论
其他文章 手脱upx
其实已经是大一下刚开始的事情了,补个档 手动脱壳の新年快乐 查壳,有壳,UPX X32dbg打开文件,查看初始断点 点击PUSHAD跟进,CTRL+*设置EIP,开始F8步过,寻找ESP寄存器第一次单个变红的地址 此时的内存窗口 开始步过 第一次步过就发现ESP单个变红,右键跟进内存窗口 然后在第一
手脱upx 手脱upx 手脱upx
LCT
\(LCT\),全称 \(Link\) \(Cut\) \(Tree\),可以解决动态树问题。 动态树(LCT) \(isroot\) 操作 如果一个点不是根,则考虑它既不是父亲的左儿子也不是父亲的右儿子。代码: bool isroot(int x){ return tr[tr[x].p].s[0]
LCT LCT LCT
OSG开发笔记(三十):OSG加载动力学仿真K模型文件以及测试Demo
前言 Osg需要打开模型文件,但是遇到显示动力学仿真的K模型文件,.k文件是一种描述材料属性的文件,比如密度、弹性模量等,该模型文件不是常规中间开放格式,无法直接支持,需要自定义解析并且重建三维模型。 Demo 实际非常流程,因为视频转gif导致部分看起来不行: 交互流畅性测试 实际研发需要用不同的
OSG开发笔记(三十):OSG加载动力学仿真K模型文件以及测试Demo OSG开发笔记(三十):OSG加载动力学仿真K模型文件以及测试Demo OSG开发笔记(三十):OSG加载动力学仿真K模型文件以及测试Demo
Ubuntu 64系统编译android arm64-v8a 的openssl静态库libssl.a和libcrypto.a
#!/bin/bash # Cross-compile environment for Android on ARM64 and x86 # # Contents licensed under the terms of the OpenSSL license # http://www.openssl
Ubuntu 64系统编译android arm64-v8a 的openssl静态库libssl.a和libcrypto.a
全面掌握 Jest:从零开始的测试指南(下篇)
在上一篇测试指南中,我们介绍了Jest 的背景、如何初始化项目、常用的匹配器语法以及钩子函数的使用。这一篇篇将继续深入探讨 Jest 的高级特性,包括 Mock 函数、异步请求的处理、Mock 请求的模拟、类的模拟以及定时器的模拟、snapshot 的使用。通过这些技术,我们将能够更高效地编写和维护
全面掌握 Jest:从零开始的测试指南(下篇)
mongo 副本集rs 理解和使用小结
转载请注明出处: 在MongoDB中,rs(通常指的是“replica set”的缩写)是复制集(Replica Set)的标识符或在使用时的一种常见前缀,尤其是在命令行工具和脚本中引用复制集时。复制集是MongoDB用来实现数据冗余和高可用性的一个核心组件。 复制集(Replica Set)的作用
一文搞定WeakHashMap
写在前面 在缓存场景下,由于内存是有限的,不能缓存所有对象,因此就需要一定的删除机制,淘汰掉一些对象。这个时候可能很快就想到了各种Cache数据过期策略,目前也有一些优秀的包提供了功能丰富的Cache,比如Google的Guava Cache,它支持数据定期过期、LRU、LFU等策略,但它仍然有可能
一文搞定WeakHashMap 一文搞定WeakHashMap
云上分布式SQL Server,你值得拥有
云上分布式SQL Server,你值得拥有 介绍Microsoft SQL Azure 是微软的云关系型数据库,后端存储又称为云 SQL Server(Cloud SQL Server)。它构建在 SQL Server 之上,通过分布式技术提升传统关系型数据库的可扩展性和容错能力。 数据模型 (1)
云上分布式SQL Server,你值得拥有 云上分布式SQL Server,你值得拥有 云上分布式SQL Server,你值得拥有