深剖关键字(跑路人笔记2)

简介: 深剖关键字(跑路人笔记)

float类型的比较

浮点数在内存中存储,并不想我们想的,是完整存储的,在十进制转化成为二进制,是有可能有精度损失的。


注意这里的损失,不是一味的减少了,还有可能增多。浮点数本身存储的时候,在计算不尽的时候,会“四舍五入”或者其他策略


如下代码:


#include <stdio.h>
int main()
{
  double f = 3.6;
  printf("%.50lf\n", f);
  return 0;
}


image.png



所以因为精度损失的问题我们一定不可以简单的将两个浮点型使用==来进行比较相同


所以我们在比较两个浮点型相同时应当比较两者相减的误差


如下代码:


//那么两个浮点数该如何比较呢?
//应该进行范围精度比较
//伪代码 
if((x-y) > -精度 && (x-y) < 精度)
{ 
    //TODO
}
//伪代码-简洁版
if(fabs(x-y) < 精度)
{ 
    //fabs是浮点数求绝对值 使用时要包含头文件math.h
    //TODO
}
//精度: 自己设置?后面如果有需要,可以试试,通常是宏定义。 使用系统精度?
//暂时推荐 
    #include<float.h> //使用下面两个精度,需要包含该头文件 
    DBL_EPSILON //double 最小精度
    FLT_EPSILON //float 最小精度



指针和零值的比较

真实转换和强制类型转换


真实的转换会改变数据存储数值如想要把"123456" ->123456 想把字符串类型转换成整形类型的数据时需要自己写算法或者使用函数来完成

强制类型转换是只转换类型内部储存的数据不变

而我们指针的零值NULL其实就是对应指针类型的0而已


我们之所以要使用NULL来代替0是为了程序员的阅读体验


void类型

void类型


首先void类型是不能直接定义变量的(因为变量是为了开辟空间void类型无空间开辟,所以编译器干脆不让通过)


void可以修饰函数或者函数参数修饰函数时表示函数无返回值,修饰函数参数时表示函数无参数(被void修饰的函数参数当你再次传参时编译器会报错或警告)


void*类型指针


void*可以直接定义变量因为指针类型开辟内存大小固定

void*类型的指针不能直接使用(毕竟指针类型决定了指针的跳跃能力,void*类型跳跃能力为0一般在强转后再使用

void*可以接收任意类型的指针可以设置成通用接口.譬如在接收函数参数使用void*类型

return关键字

我们在删除数据时并没有将数据清空而只是将数据无效化了而已


return 用于终结函数并返回函数后面的值


值得注意的是我们return的返回值一般是不能返回栈空间内变量的(栈空间内主要是临时变量)返回后一般被摧毁


return;这样写也是可以的他只做终结函数这一个功能哪怕是void类型修饰的函数也可以使用return;还终结函数


const修饰

修饰函数参数

修饰函数返回类型

修饰普通变量(依旧可以通过指针进行改变但是也告诉了其他程序员这个是不可修饰变量)

修饰数组(定义或说明他是只读变量)

修饰指针(有多情况)

const int *p //p指向的内容不可变

int const *p //p指向的内容不可变

int *const p //p的值不可变

volatile

(这个volatile关键字很少用的)


功能:防止内存变量被优化.(让变量一次次从内存中读取)


image.png


如果是仅看字面意思还是很迷惑人的,但是他的功能真的仅仅是防止修饰变量被优化.


那么这个鬼关键字有啥用呢?


(PS:这个有关多线程(你不懂其实我也不懂)的知识)


在多线程的情况下我们的变量值有可能会被改变


比如以下代码


#include<stdio.h>
int main()
{
  int flag = 1;
  while (flag);
  return 0;
}



一个简单的死循环,这时我们的变量flag很大的概率是会被我们的编译器优化的.优化后的我们的编译器就不会一次次的从内存中读取flag的变量值再进行判断了.


而是直接将flag的值放到寄存器中,或者直接不再读取flag的值而是直接进行一次次的循环运算.(对应两种优化方式)


这时我们的flag值如果发生了改变如变成0,可是我们的代码依旧在进行死循环式的运行就会出现bug.


相关文章
|
6月前
|
JavaScript 前端开发 Java
万万没想到,'this'关键字的真正威力
万万没想到,'this'关键字的真正威力
54 1
|
Java 程序员
终于不慌内卷了,多亏阿里内部的并发图册+JDK源码速成笔记
并发编程 Java并发在近几年的面试里面可以说是面试热点,每个面试官面试的时候都会跟你扯一下并发,甚至是高并发。面试前你不仅得需要弄清楚的是什么是并发,还得搞清什么是高并发! 在这里很多小白朋友就会很疑惑:我工作又不用,为啥面试总是问?真就内卷卷我呗!(手动狗头)互联网内卷已经是现在的行业趋势,而且是不可逆的,这个大家也知道;但LZ要说的是,虽然简单地增删改查并不需要并发的知识,但是业务稍微复杂一点,你的技术水平稍微提升一点的话你就会知道,并发是我们Java程序员绕不开的一道坎。
50 0
|
前端开发 容器 API
摸鱼时刻打造优弧语录,经典的你小子
各位掘友,知道juejin正式会员群里什么最多吗?
161 2
摸鱼时刻打造优弧语录,经典的你小子
|
前端开发 C语言
带你读书之“红宝书”:第十章 函数④
带你读书之“红宝书”:第十章 函数④
78 0
带你读书之“红宝书”:第十章 函数④
|
安全 前端开发 C语言
带你读书之“红宝书”:第十章 函数⑥
带你读书之“红宝书”:第十章 函数⑥
77 0
带你读书之“红宝书”:第十章 函数⑥
|
前端开发 C语言
带你读书之“红宝书”:第十章 函数⑦
带你读书之“红宝书”:第十章 函数⑦
94 0
带你读书之“红宝书”:第十章 函数⑦
|
JavaScript 前端开发 C语言
带你读书之“红宝书”:第十章 函数③
带你读书之“红宝书”:第十章 函数③
105 0
带你读书之“红宝书”:第十章 函数③
|
前端开发 JavaScript C语言
带你读书之“红宝书”:第十章 函数⑤
带你读书之“红宝书”:第十章 函数⑤
68 0
带你读书之“红宝书”:第十章 函数⑤