前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >C语言深度剖析(2)

C语言深度剖析(2)

作者头像
阑梦清川
发布2025-02-24 12:14:20
发布2025-02-24 12:14:20
3200
代码可运行
举报
文章被收录于专栏:学习成长指南学习成长指南
运行总次数:0
代码可运行

1.编程规范

函数名,变量名二者不能够冲突,尽量做到见到变量的名字,知道这个变量的意思。

变量的命名的同时进行初始化的操作,变量的英文单词首字符大写(驼峰规则);

2.复习整形数据的存储

同一段二进制的编码,让不同的数据类型进行解释(有符号的还是无符号的),就会显示截然不同的结果,因此数据的类型决定了我么如何解释二进制里面的二进制的序列;

3.条件语句

在C语言里面,我们可以把我们想要注释掉的语句放到if(0)里面,这样同样可以实现语句的注释的功能,因为在C语言里面1是真的,0是假的,如果是if(0),这样就不会执行大括号里面的语句;但是我们不建议这样做,我们仅仅需要看懂别人的这种写法;

4.布尔类型

true表示真值,false表示假的,在我们的书里面,大部分使用的是C89,C90的版本,所以并没有提及到,实际上在C99标准里面,是有这个的,使用_bool这个关键字进行定义,我们的C99使用小写的true,false进行设定,而MS还有一套自己的写法,就是全部大写,但是这样的全部大写的可以执行比较差,换言之就是代码在不同的平台执行的情况不同,有的平台可以正常运行,有的平台就不支持,因此,我们并不推荐微软的这套写法;其实布尔类型的本质和我们的C语言里面的0表示假,1表示真是一样的效果;

这个类型的使用需要包含我们的头文件stdbool.h;这个里面bool的前面没有加上短的下划线是为了和我们的C++实现兼容,C++里面就是使用的bool进行变量的定义;

5.浮点数的精度和比较

(1)浮点数的存储是存在精度的缺失

这个例子我们发现浮点数的精度是很不准确的;

(2)浮点数存储的精度问题.使得它不能直接使用==进行比较

通过这个例子我们可以得出结论:浮点数进行比较的时候,不能使用==进行比较,因为浮点数有精度的损失,比较的过程中有可能会出现各种问题;那么我们应该如何进行浮点数的比较呢,我们需要自已设置精度,也就是一个误差范围,如果误差在这个范围里面我们就可以认为这两个浮点数相等;

(3)我们可以使用自定义的宏或者是系统的宏作为标准误差

这段代码的epsilon表示的就是我们设置的一个范围只要在这个范围里面就可以认为2个浮点数相等;例如:

按照上面的写法,如果是浮点数和0进行比较,就应该写作fab(x-0)<EPS,这个时候就可以简单的写作fab(x)<EPS,这样就可以做到让浮点数和0进行比较了;

除了我们自己定义宏,我们还可以使用系统定义的宏,就是下面的这两个:

#define DBL_EPSILON

#define FLT_EPSILON这两个都是误差的精确定义,

(4)要不要写等于号的细节问题

这个时候我们就可以写作

代码语言:javascript
代码运行次数:0
复制
if(x>-DBL_EPSILON&&x<DBL_EPSILON)
{
    printf("they are the same\n");
}

这个里面实际上是省略掉了x-0,因为是和0进行比较,所以我们吧x-0简写成了x,这个时候我们是不建议使用大于等于或者小于等于的,也就是说我们尽量不要加上等于号;

6.指针和0的比较

(1)强制类型转换不会改变变量本身的二进制序列,而是我们看待这个类型的方式发生了改变,其本身的二进制序列没有改变,NULL本身就是一个0,我们通过强制类型转换把他转换成为了void*的数据类型,这样做的目的就是为了方便编译器的识别以及程序员的理解;

(2)指针和0的比较,如果直接写作p==0;就很容易让人误以为p是一个有具体的值的变量,实际上的p是一个指针,我们在比较的时候应该和NULL进行比较,因为NULL本质上就是0,只不过进行了强制类型转换。

7.switch&&case&&break&&default

(1)if语句既具有判定的功能,也具有分支的功能;

(2)switch语句里面:case具有判定的功能,break具有分支的功能;因为没有break语句的话,一个条件可以实现多条语句

(3)我们一般把default语句放到最后,用来收尾,其实default是可以出现在任何的地方的;

(4)case后面不能是const修饰的只读常量,必须是真实的常数,否则会报错;

(5)在switch语句里面的case语句里面肯定有的是用次数多,也就是频率高,我们尽量把使用频率高的放在前面,这样可以提高执行的效率

(6)一个case执行多条语句,我们尽量把执行的内容放在一个函数里面,不建议写代码块;

8.循环语句再认识

(1)getchat就是从键盘上面获取字符,返回值是int类型,为什么不是char类型呢,因为如果获取失败的话,char的数据范围0~255是无法正常进行表示的,一位char只占1个字节,也就是8个比特位,可能会发生截断现象,使得无法正常显示,因此getchar的返回类型是int整形;

(2)实际上,我们从键盘上面敲入的都是字符,例如我们敲入1234,实际上并不是正数1234,而是字符,printf("%d\n",10);只是经过如printf的格式化输出,或者是scanf的格式化输入函数,最后以其它的形式打印了出来,因此我们把键盘,或者显示器这样的设备叫做字符设备;

(3)我们都知道continue会结束本次循环,但是具体跳转到哪里呢;我们来具体的讨论一下,如果是while,do while循环,就会直接跳转到条件的判断处,对于我们的for循环,就会跳转到条件的调整地方,例如我们的for(i=0;i<10;i++);这个就会直接跳转到i++处,否则就会造成死循环;

(4)如果一个程序里面多个循环嵌套,我们尽量把循环次数少的放到外层,循环次数多的放到内层,这样可以减少CPU的存储,提高执行的效率,减少不同的循环之间的跳转的次数;

(5)我们在设置循环条件的时候,尽量写成左开右闭的形式,这样有诸多好处;就是对于同样的意思,我们可以有不同的表达,i<=9和i<10表达的意思是一样的,但是我们推荐后者,因为这样可以更加直观的计算循环的次数,不需要进行加一,减一的操作,尤其是算法题里面需要进行角标的运算,这个时候使用左闭右开[0,10)就会很方便计算;

9.void语句

(1)void本身就被编译器解释为空类型,所以不允许使用void定义变量;

(2)C语言里面的返回值可以不带类型,默认的是int类型,但是我们还是要写的,防止阅读我们的代码的人理解错误:是忘记返回值的类型,还是使用的默认的返回值的类型,为了避免这样的模棱两可的情况,我们应当写上返回值的类型(即使返回的是int类型);

(3)void修饰函数的返回值:一来可以明确的告知用户不需要返回值,二来可以告诉编译器,如果有返回值,这个返回值将无法被接受;

(4)void充当函数的参数,告知用户或者是编译器,这个函数不需要进行传参;

(5)void*可以用来定义变量,void*是指针,指针的大小是明确的,就是4/8个字节;void*可以被任何类型的指针接受,也可以接受任何类型的指针(通用接口,例如我们常见的内存函数),但是在C语言里面,我们无法对其进行解引用的操作;

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.编程规范
  • 2.复习整形数据的存储
  • 3.条件语句
  • 4.布尔类型
  • 5.浮点数的精度和比较
    • (1)浮点数的存储是存在精度的缺失
    • (2)浮点数存储的精度问题.使得它不能直接使用==进行比较
    • (3)我们可以使用自定义的宏或者是系统的宏作为标准误差
    • (4)要不要写等于号的细节问题
  • 6.指针和0的比较
  • 7.switch&&case&&break&&default
  • 8.循环语句再认识
  • 9.void语句
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档