C编程系列记录
2021/6/19 22:27:10
本文主要是介绍C编程系列记录,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 一、Linux C编程一站式学习
- switch语句
- 理解return
- 结构体
- 编码风格
- 调试工具gdb
- 完整编译C过程
- 二、vscode debug方法
- 总结
一、Linux C编程一站式学习
参考这里Linux C
switch语句
等价于if/else,但会有更优化
case只能比较常量
switch语句可以产生具有多个分支的控制流程。它的格式是: switch (控制表达式) { case 常量表达式: 语句列表 case 常量表达式: 语句列表 ... default: 语句列表 }
-
case后面跟表达式的必须是常量表达式,这个值和全局变量的初始值一样必须在编译时计算出来。
-
第 2 节 “if/else语句”讲过浮点型不适合做精确比较,所以C语言规定case后面跟的必须是整型常量表达式。
-
进入case后如果没有遇到break语句就会一直往下执行,后面其它case或default分支的语句也会被执行到,直到遇到break,或者执行到整个switch语句块的末尾。通常每个case后面都要加上break语句
理解return
在有返回值的函数中,return语句的作用是提供整个函数的返回值,并结束当前函数返回到调用它的地方。
在没有返回值的函数中也可以使用return语句,例如当检查到一个错误时提前结束当前函数的执行并返回。
结构体
编程语言中,最基本的、不可再分的数据类型称为基本类型(Primitive Type),例如整型、浮点型;
根据语法规则由基本类型组合而成的类型称为复合类型(Compound Type),例如字符串是由很多字符组成的。
有些场合下要把复合类型当作一个整体来用,而另外一些场合下需要分解组成这个复合类型的各种基本类型,复合类型的这种两面性为数据抽象(Data Abstraction)奠定了基础
在学习一门编程语言时要特别注意以下三个方面:
- 这门语言提供了哪些Primitive,比如基本类型,比如基本运算符、表达式和语句。
- 这门语言提供了哪些组合规则,比如基本类型如何组成复合类型,比如简单的表达式和语句如何组成复杂的表达式和语句。
- 这门语言提供了哪些抽象机制,包括数据抽象和过程抽象(Procedure Abstraction)
struct complex_struct { double x, y; }; struct complex_struct { double x, y; } z1, z2; struct complex_struct z3, z4; struct complex_struct z = { 3.0, 4.0 };
- 抽象
组合使得系统可以任意复杂,而抽象使得系统的复杂性是可以控制的,任何改动都只局限在某一层,而不会波及整个系统。著名的计算机科学家Butler Lampson说过:“All problems in computer science can be solved by another level of indirection.”这里的indirection其实就是abstraction的意思。
编码风格
命名风格
标识符命名应遵循以下原则:
- 标识符命名要清晰明了,可以使用完整的单词和易于理解的缩写。短的单词可以通过去元音形成缩写,较长的单词可以取单词的头几个字母形成缩写。总结出一些缩写惯例,例如:
org | 缩写 |
---|---|
count | cnt |
block | blk |
length | len |
message | msg |
trans… | x… |
-
内核编码风格规定变量、函数和类型采用全小写加下划线的方式命名,常量(比如宏定义和枚举常量)采用全大写加下划线的方式命名,比如上一节举例的函数名radix_tree_insert、类型名struct radix_tree_root、常量名RADIX_TREE_MAP_SHIFT等。
-
全局变量和全局函数的命名一定要详细,不惜多用几个单词多写几个下划线,例如函数名radix_tree_insert,因为它们在整个项目的许多源文件中都会用到,必须让使用者明确这个变量或函数是干什么用的。局部变量和只在一个源文件中调用的内部函数的命名可以简略一些,但不能太短。尽量不要使用单个字母做变量名,只有一个例外:用i、j、k做循环变量是可以的。
-
禁止用汉语拼音做标识符,可读性极差。
函数
每个函数都应该设计得尽可能简单,简单的函数才容易维护。应遵循以下原则:
- 一个函数只是为了做好一件事情,不要把函数设计成用途广泛、面面俱到的,这样的函数肯定会超长,而且往往不可重用,维护困难。
- 函数内部的缩进层次不宜过多,一般以少于4层为宜。如果缩进层次太多就说明设计得太复杂了,应考虑分割成更小的函数(Helper Function)来调用。
- 函数不要写得太长,建议在24行的标准终端上不超过两屏,太长会造成阅读困难,如果一个函数超过两屏就应该考虑分割函数了。[CodingStyle]中特别说明,如果一个函数在概念上是简单的,只是长度很长,这倒没关系。。
- 执行函数就是执行一个动作,函数名通常应包含动词,例如get_current、radix_tree_insert。
- 比较重要的函数定义上侧必须加注释,说明此函数的功能、参数、返回值、错误码等。
- 另一种度量函数复杂度的办法是看有多少个局部变量,5到10个局部变量已经很多了。
indent工具可以把代码格式化成某种风格
indent -kr -i8 main.c
调试工具gdb
调试的基本思想仍然是“分析现象->假设错误原因->产生新的现象去验证假设”这样一个循环,根据现象如何假设错误原因,以及如何设计新的现象去验证假设
- 单步执行和跟踪函数调用
- 断点
- 观察点
- 段错误
完整编译C过程
- 汇编与C
gcc main.c -g # -g objdump -dS a.out #objdump反汇编时可以把C代码和汇编代码穿插起来显示
要查看编译后的汇编代码,其实还有一种办法是gcc -S main.c,这样只生成汇编代码main.s,而不生成二进制的目标文件
gcc -S main.c cat main.s
汇编程序的入口是_start,而C程序的入口是main函数
以前我们说main函数是程序的入口点其实不准确,_start才是真正的入口点,而main函数是被_start调用的
- 编译连接详细过程,参考这里
#1. 预处理preprocess (# 加头文件,替换宏等) gcc -E test.c -o test.i #2. 编译compiling,生成汇编代码(仍然是文本) gcc -S test.i -o test.s #3. 汇编Assembling, 生成目标文件(二进制) gcc -c test.s -o test.o #4. 链接Linking,生成可执行文件(二进制) gcc test.o -o test
这些选项都可以和-o搭配使用,给输出的文件重新命名而不使用gcc默认的文件名(xxx.c、xxx.s、xxx.o和a.out)
二、vscode debug方法
参考这里
- 安装插件c/c++
- 选择c++ edit Configurations(json),会生成c_cpp_properties.json
- Run and Debug,选择gcc调试,会生成launch.json
调试方法,添加断点(一般在每个函数入口处添加便于观察函数内部),Variables会看到变量的变化。
总结
提示:这里对文章进行总结:
这篇关于C编程系列记录的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享