深剖关键字(跑路人笔记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.


相关文章
|
消息中间件 前端开发 调度
C++20 协程——你还只是听过?觉得没时间了解,这里可以帮到你。五分钟 从没听过到使用的帮助手册
来源:协程是在C++20 标准中提出的一个新的工具。 它突破传统的程序在cpu中来回切换时需要更新和恢复PCB资源现场的耗时操作(多进程)或者COW(低级调度)操作时间。
247 0
|
7月前
|
JavaScript 前端开发 Java
万万没想到,'this'关键字的真正威力
万万没想到,'this'关键字的真正威力
62 1
|
设计模式 缓存 算法
花了30天才肝出来,史上最全面Java设计模式总结,看完再也不会忘
Design Patterns: Elements of Reusable Object-Oriented Software(以下简称《设计模式》),一书由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides合著(Addison-Wesley,1995)。这四位作者常被称为“四人组(Gang of Four)”,而这本书也就被称为“四人组(或 GoF)”书。他们首次给我们总结出一套软件开发可以反复使用的经验,帮助我们提高代码的可重用性、系统的可维护性等,解决软件开发中的复杂问题。
173 0
|
存储 编译器 C++
类和对象(跑路人笔记)<完>(3)
类和对象(跑路人笔记)<完>
类和对象(跑路人笔记)<完>(3)
|
存储 编译器 Linux
类和对象(跑路人笔记)<完>(1)
类和对象(跑路人笔记)<完>
类和对象(跑路人笔记)<完>(1)
|
编译器 C++
类和对象(跑路人笔记)<完>(2)
类和对象(跑路人笔记)<完>
类和对象(跑路人笔记)<完>(2)
|
编译器
类和对象(跑路人笔记)<完>(4)
类和对象(跑路人笔记)<完>
类和对象(跑路人笔记)<完>(4)
|
开发框架 .NET 编译器
自定义类型(跑路人笔记2)
自定义类型(跑路人笔记1)
自定义类型(跑路人笔记2)
|
编译器 C++
自定义类型(跑路人笔记1)
自定义类型(跑路人笔记)
自定义类型(跑路人笔记1)
|
编译器 C语言 C++
new/delete详解(跑路人笔记)<C++初阶>
new/delete详解(跑路人笔记)<C++初阶>
new/delete详解(跑路人笔记)<C++初阶>