C++学习笔记:油管博主Cherno

【25届秋招备战C++】最强C++学习教程:Cherno C++笔记 纵览各种CPP教学视频,这是最接近底层逻辑的,生动有趣,举例精准贴切,希望所有在C++学习之路“踽踽独行”又迷茫困顿的初学者可以通过Cherno的视频理解C++,编程或许可以很有趣。 阅读详情

1、用include<iostream>包含文件后,在编译时,iostream文件内的内容就会被拷贝粘贴放入当前的文件中include该行的位置。

2、当使用自定义函数时,不需要include包含函数定义的文件,只需要在头部加上该函数的声明void Log(const char* message)即可,在对整个工程构建(build编译所有文件)时,链接器会找到Log函数的定义在哪里,将函数定义导入到Log函数中。

3、cpp文件也叫做translation unity(编译单元),每个cpp都会被编译器编译成一个obj。当一个cpp文件中include多个cpp时,依旧只有一个translation unity(编译单元),对应生成一个obj。这就是translation unity(编译单元)和cpp文件术语上区别的原因。

4、c++中文件只是存放代码的一种方式,只需要告诉编译器这个文件的类型和编译器该如何处理它

5、编译器在preprocessing预编译阶段检查并评估所有的pre-processing(预编译)语句,常见的pre-processing(预编译)语句:include,define,#if和#ifdef。任何一个以#号开头的语句都被成为预处理命令,或叫预处理指令

6、define的作用是搜索这个词然后把他替换成后面的东西。

7、obj文件是二进制码

8、编译器优化,在生成的obj文件中,去掉一些不必要(重复的)汇编代码执行部分

(但在嵌入式中,这是噩梦,所以要用Volatile来定义一些变量,防止优化)

9、在编译时,就可完成任何常量的计算,不必等到运行时。constant folding(常量折叠)

10、编译:根据源代码文件(source file)生成包含机器码和我们定义的常量数据的二进制文件(object file)。有了object文件后,就可以把这些文件链接到一个包含所有我们最终要执行的机器码的可执行文件。

11、编译过程(产出obj):(1)预处理代码,预处理语句评估(作用)(2)进入标记解释(tokenizing)和parsing(解析阶段),将“英文”C++文本处理成编译器能懂和处理的语言。(3)结果就是创建某种叫做abstract syntax tree(抽象语法树),也就是我们代码的表达,但是是以抽象语法树的形式。(4)创建抽象语法树后,就开始产生代码,即真正的cpu会执行的机器码。

12、C开头-编译阶段错误,LNK开头-链接阶段错误

13、程序入口点不一定是叫做main的函数(默认是main),主要看在编译器中如何设置

14、Link只会链接调用到的函数,没有用到的函数不会去链接它。但若是在主函数所在文件中定义的函数,虽未被调用,但也会链接它,因为这个函数可能在别的文件被调用到

15、当项目中存在多个同名的函数(特别当在头文件中定义时),链接器会报错,因为它不知道该链接哪个。解决方式共有三种:

(1)可以在函数声明前加上staitc,即表示该函数只在该文件内有效。

(2)使用inline,即当这个函数被调用时,直接将函数体的内容拿过来取代调用。

(3)不在include.h中定义函数,而是放在同名的include.c中,.h中只含有该函数的声明,这样子头文件在多次被包含时,就不会被编译器用以加入整个函数体,而是只在该位置加入函数的声明,避免了多个文件中重复定义函数。

16、当我们在头文件中放置函数声明时,调用该头文件,只会在调用文件处加入该函数的声明,并在链接阶段,让链接器自己去工程文件中找到这个函数的定义来使用它。

17、函数声明的作用!:

(1) 当函数定义不在该cpp文件时,告诉它,有这个函数存在,只是它定义于别的地方。

(2) 告诉所在文件,有这个函数的定义

(3) 函数的声明实质就是函数定义的第一行。只有知道函数声明,也才能知道如何去调用它

18、头文件:

(1)省去了每次复制粘贴函数声明的工作,只需要在头文件中写函数声明。

(2) 在cpp被编译时,声明会被自动复制粘贴到include头文件的位置。

(3)头文件(如Log.h)里声明的函数,不用是和它相同文件名cpp里定义的函数,任何函数(如void InitLog())声明都可以,与文件名没有任何关系。

(4)包含头文件的意思,也只是把头文件中的内容复制粘贴到包含的位置。

(5)头文件名和cpp名相同,通常包含的函数也相同,只是因为这样子看起来架构更合理,更清晰一点而已。

(6)函数的定义:在链接阶段,调用这个函数的(目标)文件会来链接它,无论它写在哪个cpp文件中。

19、头文件保护符

(1)#pragma once:新的保护符,只用写一行。

(2)

#ifndef_LOG_H

#define_LOG_H …

#endif

老保护符,较为麻烦。

20、头文件包含方式

(1)<>从include目录中去找(系统包含的标准库)

(2)””从当前相对目录(自己写的文件)和从include目录去找,相当于可以包含所有文件。

21、c标准库和c++标准库的区别:c标准库头文件有.h,c++直接是名字。

22、一个程序实际上是由内存组成的。

23、数据操作符实际上都是在标准库等有人写好的函数,我们直接调用。大部分的原始数据结构,实际上在检查两个整数是否相等时,是逐个字节逐个位进行比较的,在内存中对应位的二进制数都得相同。

24、VS中debug运行状态,右键选择go to disassembly(ctrl+G),可显示源代码及其对应的汇编代码。但还是尽量避免debug汇编语言,用来查询错误太难。但用来快速查看编译器产生了什么样的代码,还是挺有用的

25、C++变量

(1)不同数据类型间,真正的唯一区别是大小(分配多少内存)

(2)unsigned(无符号数),用于去除变量类型的符号位(1位)。unsigned int

(3)5种最基本的数据类型

类型

char

short

int

long

long long

所占字节数

1字节

2字节

4字节

4(看编译器)

8字节

(4)定义float变量时,数值后面要+f,否则会被当成double。float variable = 5.5f;

(5)float4字节,double8字节

(6)bool变量只能为"true"和"false"实际值为1和0。除了0以外的任何整数都是1。

(7)bool变量占用一个字节byte,但实际上只需要一个位bit,但由于计算机中的寻址是按字节byte来的,所以需要占用一个字节来找到它,我们也可以将8个bool存放在1个byte里。

25、if语句

(1)else if实际上就是被写在了同一行而已

else

{

       if()

}

实际上和else if一样的,其实就是个else和if。C++定义中也没有else if这样的关键字,仅仅是else和if

(2)if语句中通过比较条件,跳转到内存的其他部分执行指令,如果语句和分支分布在内存距离较远的地方,需要的时间就长。高效代码会尽量减少if语句。

26、编程有两重要的组成部分(1)数学编程(2)逻辑编程

if语句、条件语句、循环、控制流语句是可以用来修改程序运行情况的唯一工具。

27、控制流语句:

(1)continue:跳过本次迭代,直接进入下一次

(2)break:直接跳出整个循环

(3)return:完全退出函数。return可写在任何地方

28、内存是计算机的一切,编程中唯一最重要的东西,可能就是内存(memory)。当你写一个应用程序并启动它时,整个的程序被载入内存,在你写的代码中,所有的指令告诉计算机要做什么,所有的这些都被加载到内存中,这就是CPU如何访问你的程序并执行指令的。

29、指针:

(1)所有类型的指针都是一个整数,存放一个地址

(2)指针本身没有类型,类型只是说它存放的地址中的数据,可能是这个类型

(3)给指针初值0(也就是NULL),实际只是意味着这个指针无效,0是无效的,内存中没有0这个内存地址。

(4)但如果指针类型是void,在对它指向内存操作(赋值)时,会报错,因为不知道这块数据是short两个字节,还是int四个字节,就无法完成操作。

(5)指针本身也是变量

(6)指针的大小根据操作系统位数,看它的内存地址是多少位的,一般是32位4个字节

30、引用:

(1)引用实际上只是指针的一个扩展,本质上引用就是指针。

(2)引用只是基于指针的一种语法糖,使得代码更易读易写。

(3)引用不像指针要先创建一个指针变量,“引用”必须引用一个已存在的变量,其本身并不是一个新变量。它只是其他变量的引用。引用必须要有初值。

(4)int&中&是类型的一部分,表示引用。

(5)int& ref = a;ref并不是真的变量,只是在代码中当成一个变量使用,在编译时,也不会创建一个ref的变量。但可以将ref就当成a来使用。ref就是a的别名。

(6)&引用就是变量本身,不是它的地址。ref就是a

(7)引用一旦声明,就无法改变它所指向的对象,即ref已经是a的变量,就不能再变成b的别名。

31、类:

(1)一种将数据和函数组织在一起的方式。

(2)类名必须唯一,类基本上就是创建了一个新的变量类型。

(3)由类类型制成的变量叫做对象,新创建对象的过程叫做实例化。

(4)默认情况下,类中成员的访问控制都是私有的,只有类内部函数才能访问这些变量。

(5)类内的函数称作method(方法)

(6)struct和class的唯一区别是,struct默认是公有的(public)

(7)当结构体使用继承时,会收到警告,但依旧可以运行,但是用类就不会有这样的问题。

(8)当只是包含一些变量结构时,通常采用结构体好些。当包含大量功能时,用类好些。

(9)在技术上说,可以在任何使用class的地方使用struct,就是可见性上的区别

(9)构造函数会在你每次实例化类的时候,自动调用

(9)可以有很多同名,但不同参数的构造函数(函数重载)

(10)创建对象时不会自动给变量赋初值,构造函数默认也是空函数,必须要手动赋初值,否则就是之前留在内存中的值,可能也无法用公共的std::count函数打印。

(11)可以用delete告诉编译器,我不想要那个默认构造函数Log() = delete;,该类就无法创建对象,而只能调用其中方法。也可以用private来隐藏构造函数

32、类的写法

(10)成员变量前加上m_进行标注,以便和局部变量(用于函数等)区分开。

(11)写法习惯:有两个public,public方法放在一部分,public变量放在另一部分。同时public static变量放在另一部分。

33、类中的static

(1)static在类中有两种:在类class或结构体struct外使用static,或在类内和结构体内使用static

(2)类外的static修饰的符号(定义的函数和变量)在link(链接)阶段是局部的,只对定义它的编译单元(.obj)可见。类内的static表示这部分内存是该类所有实例共享的,即实例化很多次这个类,但这个静态(static)变量只会有一个实例。

(3)静态方法同样,只有一个,静态方法中没有该实例的指针(this)

(4)静态方法不能访问非静态变量,静态方法没有类实例,没有获得当前的类实例作为指针(this指针)

(5)函数中的静态变量,生命周期是整个程序,作用域是函数内.

(6)使用静态类方法,可以直接创建一个类的实例。

(7)两个全局变量即使在不同的文件中,也不能同名,在link(链接)时,会同时检测到两个同名全局变量,重复定义。

(8)extern相当于引用,当变量前加了extern就会去其他文件找到已经定义的这个同名变量,成为它的引用。

34、枚举值设置:

enum Example

{ A, B, C};

(1)创建的这个枚举类型叫Example,用Example类型定义变量时,它的值也被限定在了这三个值之一。

(2)默认从0开始,即A为0,B为1,C为2

(3)也可赋值任意整数。A=5,此时B、C自动顺延为6、7。

(4)枚举值默认类型是32位整数,可以设置枚举值的数据类型。例如8位整数:

enum Example : unsigned char

(5)数据类型只能是整形,不能是像float,但可以是char(进一步说明char是种整形数据类型)

35、构造函数:

(1)构造函数会在你每次实例化类的时候,自动调用

(2)可以有很多同名,但不同参数的构造函数(函数重载)

(3)创建对象时不会自动给变量赋初值,构造函数默认也是空函数,必须要手动赋初值,否则就是之前留在内存中的值,可能也无法用公共的std::count函数打印。

(4)可以用delete告诉编译器,我不想要那个默认构造函数Log() = delete;,该类就无法创建对象,而只能调用其中方法。也可以用private来隐藏构造函数。

36、析构函数:

(1)当一个对象被销毁时,析构函数都会被调用.

(2)可用于栈(直接创建)和堆(new创建)。

(3)析构和构造唯一区别,函数前的波形符(~)。~Entity()

(4)调用类的函数结束后,即}符号后,会自动调用析构函数,销毁对象,避免内存泄漏。

37、继承

class Player : public Entity

(1)把一系列类的所有通用代码(功能)放到基类(父类)中,这样就很容易从基类中创建派生类。避免重复代码

(2)父类中任何不是私有的(private)成员,子类都可以访问

(3)继承只能继承公有public的部分

(4)Player不仅仅是Player类型,还是一个Entity类型。Player也是一个Entity。

(5)可用在任何想用Entity(父类)的地方使用Player(子类)。子类总是父类的一个超集。

(6)继承是用来扩展类和为基类提供新功能的一种方式。

38、虚函数

B是A的子类

(1)在A中新建一个方法标记为虚函数,那么就可以在B类中重写这个方法让去做其他事情。

(2)用虚函数的原因:在类中正常声明函数或方法,当调用该方法时,总是会调用属于这个类型的方法。然而我们实际上是想调用它子类类型中的方法

(3)但希望让C++能意识到,我们传入的其实是一个Player,所以请调用Player的GetName,这就要用到虚函数

(4)虚函数引入了一种要动态分派的东西,一般通过虚表(vtable)来实现,虚表即一个包含类中所有虚函数映射的列表。通过虚表可以在运行时找到正确被重写的函数

(5)虚函数:父类函数名前面加上virtual,子类函数名后加上override

(6)虚函数的额外成本:

a、需要额外的内存存储虚表,基类内还有一个指针成员指向虚表

b、每次调用虚函数时,需要遍历虚表找到最终要运行的函数。

39、纯虚函数:

(1)允许定义一个在基类中没有实现的函数,强制子类去实现这个函数

(2)基类(父类)中缺乏定义,直接=0(相当于没有定义)

(3)纯虚函数必须在子类中实现,才能创建这个类的实例。

(4)有纯虚函数的类,称为接口

(5)可将虚函数的类作为参数传入通用函数,即可调用这个函数(完成多个类同一功能的输出)

40、可见性

(1)C++中三个基础的可见性修饰符:private和protected、public。

(2)protected比private更可见,比public更不可见。即所有子类可以访问,但外部不可见。

41、数组

(1)数组基本上就像在一个变量中有多个变量。

(2)如果想打印整个数组,需要打印这个数组的地址(数组名)

(3)数组连续的存储数据,即他们的内存地址是连续的。

(4)访问数组中的特定索引,实际上是通过对内存取偏移量实现的。例如 int example[5]。如若要访问example[2],因为是int四个字节,内存地址总共增加(偏移)2*4=8个字节。

(5)在栈上创建的(正常创建),到达函数最后花括号会被销毁。在堆上创建的(用new),除非程序主动用delete销毁,否则始终处于活动状态。

(6)用new创建数组时用了数组操作符[ ],所以delete后也要加上[ ],即delete[ ]

(7)std::arraya,C++11中带有的数组,有边界检测、记录数组大小等功能,但也意味着额外的开销。

(8)永远都不要在数组内存中访问数组的大小,但可以用sizeof()得到这个数组占了多少字节,然后除以它的数据类型的大小,得到数组元素个数(大小)。但sizeof通常不能用于堆上创建的数组,因为要访问它,通常要通过一个指针,sizeof得到的也只是那个指针的大小(4字节)。

(9)但使用sizeof计算数组大小也有危险,当数组在函数(可能已经销毁)或者变成了指针,会出错

(10)在栈中创建数组时,数组大小这个值必须在编译时就要知道的常量。(C++特性)

static const int exampleSize = 5;

(11)类中的常量表达式必须是静态

42、字符串:

(1)字符就像是字母、符号和数字以不同的形式展示出来

(2)C++中char字符类型占一个字节,默认处理字符方式是ASCII字符(256个刚好一个字节数量)

(3)字符类型可以大于一个字节,当要使用到例如中文时,一个字节(256种可能)明显放不下,就可能要扩展为两个、三个、四个字节的字符。当要把它和英文字母、数字、符号放在一起时肯定远远多于256

(4)字符串是一个固定分配的内存块,不可能让它变得更长,通常创建时直接用const

(5)C++中用双引号定义字符串时,它其实就是const char数组,使用std::string 时要加上const

(5)C++中的字符是用单引号,不是双引号,双引号默认是char指针。

char* name = “Cherno”;

char name2[7] = { ‘C’, ‘h’ , ‘e’ , ‘r’ , ‘n’ , ‘o’ , ‘/0’ }

(6)C++标准库有个类叫string,还有个模板类basic_string。

(7)std::string本质上是这个basic_string的char作为模板参数的模板类实例,即模板特化(template specialization)。就是把char作为模板类basic_string的模板参数,意味着char就是每个字符背后的数据类型。

(8)若要打印处字符串,需要再引入string库,即使iostream库中已经包含string定义。因为在string头文件中这个操作符的被重载实现了允许我们把字符串传入输出流

43、字符串字面值:就是在双引号之间的字符“cherno”

(1)字符串字面值是存储在内存的只读部分的,无法通过指针只想改变它的值。只能把它重新赋值给一个新建数组,再对这个数据进行修改

(2)C++11后,用指针指向字符串前必须要加上const,本身字符串字面值也是不可改变,const相当于使用时限制了这一操作,防止出错。

(3)字符串前写上字母R,意味着它会忽略转移符

44、const

(1)承诺某些东西不会改动,但对实质性内容没有修改。这个“承诺”可以绕过。如:强制类型转换 a = (int*)&MAX_AGE

(2)使用const后,当你还尝试去改动时,编译器会提醒报错。

(3)指针:

a、const在类型前:不能改变指针指向的内存地址的内容。const int* a = new int;

b、const在类型后:不能改变指针指向的内存地址。         int* const a = new int;

c、const后跟*:和在类型作用前一样。int const* a = new int;

d、结合a和b:既不能改变指向,指向的内容也不能变。const int * const a = new int;

(4)类:

       a、对类的方法:表示该方法只能读取,不会修改类中数据(包括成员变量)。

       b、在方法的声明后加上const

(5)引用:

       a、加上const后不能做任何修改,因为引用就是那个对象

b、方法定义时没用const,而调用时用了 const类,则无法用方法

(6)mutable关键字:定义变量后,即使有const也可以修改。

45、mutable关键字:有两种用法

(1)和const一起使用

(2)用在lambda表达式里(函数声明后),或同时也和const一起使用。

auto f = [=]() mutable

(3)lambda类似个一次性的小函数,可以将它赋值给一个变量。

46、栈的空间通常较小,堆的较大,栈中的变量生命周期在声明它的地方就指定了,堆中创建的变量(内存)需要手动删除才能释放

47、(1)用new创建对象时,要用ListNode* dummyHead = new ListNode(0); 要加上*,因为new分配内存后的返回值是该类型的指针(该块内存的首地址)

(2)调用new时候,会调用C中的malloc(sizeof(Entity))分配内存,但是比起malloc,new会调用构造函数。

48、explicit在构造函数前声明后,构造函数就不能隐式的进行类型转化,只能显式的进行

49、C++中运算符就是函数,例如add这样的操作可以交给+运算符。

50、浅拷贝:没有实际复制一个新的存储空间,相当于只是拷贝了指针,指向相同的内存。

深拷贝(定义了拷贝构造函数):在复制同样的对象时,开辟了新的存储空间,相当于拷贝了一个新的对象。

51、箭头运算符:当指针指向一个对象时,搭配->可以访问该对象的成员和方法。:
Entity* ptr = &e;  ptr->Print();   (Print是e中的方法)

52、标准库也被称为标准模板库,标准模板库本质上是一个库,装满了容器,容器类型,这些容器可以包含特定的数据,可以模板化任何东西。

53、vector本质上是一个动态数组ArrayList,大小长度可变。当添加新的元素的时候,会寻找一个更大的存储空间,将现有的元素复制过去。

vertices.push_back():添加元素

vertices.erase():删除元素

Array会在栈上创建,而vector会把它的底层存储在堆上,技术上看,返回std::array会更快

std::vector是C++标准模板库中的类

54、dll是运行时动态链接库,在运行时动态链接。

lib是静态库,静态链接是在编译时发生的

55、tuple(元组):一个类,可以包含x个变量,但它不关心类型(类型可以不同)

56、(1)模板就是让编译器帮你写代码;

(2)模板并不是实际存在的,只有被调用时,才会被创建。

(3)调用时等价于复制这个函数,然后把类型自动替换为我们需要的

57、

栈分配:有栈指针,当遇到变量创建时,反着移动需要的空间字节位置,空出内存进行分配,返回栈指针的地址。当作用域结束时,直接弹出,栈指针回到作用域之前的位置。(多个不同变量时,也是连续的存储空间,只是中间添加安全守卫(一些数据cccc))

堆分配:堆用new分配时,(实际调用了malloc)从“空闲列表中”寻找符合空间大小,空闲的内存空间。

堆上分配内存是一堆的事,栈上就只像一条cpu指令

58、auto具有两面性:(1)当更换类型时,不用太多的修改 (2)但当原先类型调用了它单独有的方法时,可能会报错,比如string类型的name.size()

59、静态数组:不增长的数组。std::array<int, 5> data;

相比普通的 int data[5];静态数组是个类,存储了它的大小可以直接访问:data.size()

60、lambda:匿名函数,相当于用完即弃的函数,在代码过程中生成。

61、类本身也是个命名空间

62、多维数组其实就是数组的集合,二维数组是数组的数组,三维数组是数组的数组的数组

二维数组:每个元素包含了50个int型的数组,元素是指向该数组的指针

三维数组:在外层又套了层指针的数组,每个指针指向一个数组的数组

63、指针就是一个整数,和指针类型(类似int型指针)无关。

64、排序:std::sort(values.begin(), values.end());若不加第三个参数则默认升序排序。

第三个参数可以是自己创建的结构体内的函数,也可以是一个lambda,也可以是内置函数。如std::sort(values.begin(), values.end(), std::greater<int>()); 从大到小排序

65、类型双关:拥有的一段内存,当作不同类型的内存对待。将该类型作为指针,然后转换为另一个指针,如果有必要,还可以进行解引用。

66、虚析构函数:不是覆写析构函数,而是加上一个析构函数

只要些一个要扩展的类或者子类时,(允许一个类拥有子类),必须要声明你的析构函数是虚函数

67、左值是有某种存储支持的变量,右值是临时值;左值引用仅仅接收左值,除非是用const,右值引用仅仅接受右值

68、参数计算顺序:

int value = 0;

PrintSum(value++, value++); C++中对不同参数是并行计算的,所以值可能是0,0

C++17以后要求必须是有顺序的,但是具体顺序仍然是未定义的,也就是值可能是0,1或1,0

69、C++三法则:如果需要析构函数,则一定需要拷贝构造函数和拷贝赋值操作符。

Cherno C++ P28 C++接口(纯虚函数) Cherno C++学习笔记 阅读详情

相关推荐

国外大牛cherno的vs设置,修改后适用于vs2022版本

国外大牛cherno的vs设置,修改后适用于vs2022版本,应用时可以只选择应用字体和代码颜色选项

Cherno C++笔记

很久前在油管上看的大神cherno的c++教学视频,现在已经更新到了100P左右了。最近这段时间发现自己过去的时间里其实学了很多东西,但是一直没有时间总结,所以更新总结一下,也给自己梳理一下所学知识。关于cherno的笔记网络上有很多,我在写自己的笔记的时候因为时间比较久远,有些知识点会遗忘,也会一定参考别人的笔记,会在文末进行标注。1.欢迎来到C++ 使用c++的主要原因是可以直接控制硬件。c++写代码,代码被送去编译器进行编译,编译器会将代码输出为目标平台的机器码。机器码就是CPU实际上在运行的指令集。

weixin_44683202的博客 4481

LLVM实战:如何用Clang+LLVM打造你的第一个C++编译器(附完整配置步骤)

本文详细介绍了如何使用Clang+LLVM构建C++编译器的完整配置步骤,从环境准备到编译流程剖析,再到调试与优化技巧。通过实战指南,帮助开发者深入理解LLVM编译器框架的工作原理,并掌握交叉编译与性能分析等高级功能。

sprite的博客 746

跟着Cherno大神的C++学习笔记

include指定了你想要包含的文件,预处理器打开了文件,阅读所有内容,粘贴到你写的文件中。CPP文件被称为翻译单元,实际上C++不关心文件,文件只是提供给编译器源代码的一种方式,你需要告诉编译器你输入的是什么类型的文件,以及编译器应该如何处理它。有时在cpp文件中包含其他cpp文件,变成一个大的cpp文件,你会得到一个翻译单元,一个obj文件。编译器做了如下几个事:1. 预处理我们的代码,当预处理完成,我们的文件会被记号化和符号化,将C++语言整理成编译器真正能够理解和推理的格式,也就是所谓的。

weixin_43046168的博客 1945

Qt图表库三选一:Qwt、QChart、QCustomPlot实战性能对比与避坑指南

本文深入对比了Qt开发中三大主流图表库Qwt、QChart和QCustomPlot的性能与适用场景。通过实测数据展示各库在渲染效率、内存占用和功能特性上的差异,并提供针对不同项目需求的选型建议和集成避坑指南,帮助开发者高效选择最适合的Qt图表解决方案。

weixin_33691700的博客 449

Zemax中场曲与畸变图的深度解析与应用场景对比

本文深度解析了Zemax中场曲/畸变图与网格畸变图的核心原理、计算逻辑与适用场景。通过对比常规成像镜头、扫描镜头、鱼眼镜头及变形宽银幕镜头等实际案例,详细阐述了如何根据系统对称性、视场角及核心需求选择正确的分析工具与畸变评价标准,为光学设计中的畸变诊断与优化提供清晰指导。

sand8的博客 480

YouTube Cherno C++ 学习笔记以及重点总结(持续更新)

个人学习总结记录,错误地方还请指正!

jq1010的博客 1318

TC3xx系列LMU与SPR实战:将关键算法从Flash搬移至PSPR提升5倍执行效率

在实际电机控制项目中,通过将FOC算法全部迁移到PSPR,我们不仅将执行时间从56μs降至11μs,还将最坏情况下的时间偏差控制在±0.3μs以内。实测数据:在TC397上执行Flash中的32位浮点矩阵乘法,平均每条指令需要8.7个周期,而同样的代码在PSPR中仅需1.2个周期。传统开发中,工程师往往将所有代码放在Flash中运行,这相当于让F1赛车在乡村公路上行驶。迁移后不仅平均执行时间缩短,更重要的是时间抖动从±15%降低到±2%以内,这对闭环控制系统至关重要。不是所有代码都适合迁移到PSPR。

weixin_31421613的博客 296

cherno c++学习笔记(更新中) (最好的C++教程)B站转载的视频名称叫这个(1 - 46)

1. 预处理就是将里面的内容拷贝到目前文件中。 2.预处理里面的#define A b 就是把A改成b显示在编译后。 3.函数申明不一定在本文件里,也可能在其他文件,但必须在某处。 4.

xu1009的博客 4219

MaxEnt物种分布预测中的常见误区与优化技巧:如何提高模型准确率

本文深入探讨了MaxEnt物种分布预测模型从基础应用到精准预测的进阶实践。针对模型准确率提升,文章系统分析了环境变量筛选、模型参数调优、结果批判性解读等核心环节的常见误区,并提供了基于生态位模型原理的深度优化技巧,帮助研究者产出更可靠、可解释的预测结果。

weixin_29219539的博客 594

模仿学习(Imitation Learning)概述

什么是模仿学习呢?简单来说,模仿学习(Imitation Learning),就是要训练机器能够复制人类的连续动作,进而达到模仿的目的。其实,Imitation Learning的实用性很高,假设今天有一个训练场景,你不知道该怎么定奖励值(reward),但是你可以收集到专家的示范数据(expert demonstration data),你就可以考虑用Imitation Learning这个方法。因此,模仿学习也被寄予很高的期待,成为下一代强人工智能的关键技术。......

qq_22749225的博客 2万+

Cherno_游戏引擎系列教程(1):1~16

文章目录1. Introducing the GAME ENGINE series!2. What is a GAME ENGINE3. DESIGNING our GAME ENGINE4. Project Setup Game Engine Series5. Entry Point Game Engine Series6. Logging Game Engine Series7. Premake Game Engine Series8. Planning the Event System Game En

weixin_47652005的博客 4299

KUKA-外部自动运行模板程序——个人设计模式&思路

用于说明KUKA与西门子PLC外部自动交互模板的设计思路与使用流程

qq_39024187的博客 5603

Cherno_游戏引擎系列教程(3):44~73

文章目录44. Shader Asset Files Game Engine series45. Shader Library Game Engine series46. How to Build a 2D Renderer Game Engine series47. Camera Controllers Game Engine series48. Resizing Game Engine series49. Maintenance Game Engine series50. Preparing for 2

weixin_47652005的博客 4628

Transformer模型详解

​本文主要介绍Transformer系列,从基础到理论,对注意力机制进行总结并解释《Attention is all you need》,提出解决sequence to sequence问题的transformer模型,用全attention的结构代替了lstm,抛弃了之前传统的encoder-decoder模型必须结合cnn或者rnn的固有模式,只用attention。文章的主要目的是在减少计算量和提高并行效率的同时不损害最终的实验结果。

专注大数据与人工智能技术分享,欢迎私信加群互相学习! 5276

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

跟着Cherno学习C++(二)——基础语法1

C++语法从入门到精通(二),跟着Cherno学习C++

weixin_45813633的博客 1349

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

C++学习笔记-Cherno(32位环境)

Cherno的C++系列学习笔记

weixin_44344557的博客 1868

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Cherno C++ basic

Day 1 (2022.4.26) // 在#后面的都是预处理语句,编译器收到源文件后首先处理预编译语句(发生在实际编译之前) // #include <iostream> 将iostream文件的所有内容拷贝到当前文件,之所以要拷贝,是因为需要一个被 // 调函数的声明 // main函数不写return则默认返回0 // 重载运算符其实是函数 std::cout.print("Hello World!").print(std::endl); // std::cin.get() 等

Devlegal的博客 1223

Cherno C++ 学习(一)

1. vs有两种默认的方式,debugrelease,其中在项目的C++属性栏中,debug模式下里面的Optimization是默认关闭的,而release模式是默认开启的,所以Optimization会加速程序运行,但是不适合Debug。 2. 头文件是在预处理阶段编译的,实际编译时,Compiler编译的只有cpp文件,每一个cpp文件都会被单独编译,然后每一个cpp都会生成一个其对应的(v...

alexhu2010q的博客 2157

cherno c++学习笔记(更新中) (最好的C++教程)B站转载的视频名称叫这个(47- )

目录57.动态数组(std::vector)特别是标准库中的 vector类,现在开始写一些 C++标准库里的东西,这个还是很重要的。标准库,在这种情况下应该叫标准模板库,本质上就是一个库,里面装满了容器,容器类型,这些容器包含特定的数据,之所以被称为标准模板库,因为它可以模板化任何东西。整个库模板化意味着容器的底层数据类型。可以说容器包含的数据类型,实际上是由你决定,所有东西由模板组成。使用模板库并不需要多了解模板,只要知道模板可以处理你提供的底层数据类型,这意味着你不需要编写自己的数据结构或类似的东西。

xu1009的博客 997

Cherno_游戏引擎系列教程(4):74~100

文章目录74. Where to go next + Code Review Game Engine series75. Entity Component System Game Engine series76. Intro to EnTT (ECS) Game Engine series77. Entities and Components Game Engine series78. The ENTITY Class Game Engine series79. Camera Systems Game En

weixin_47652005的博客 5381

cherno大神c++自学笔记

x86 32位 操作系统 x64 64位操作系统声明 declaration 定义 definition注意 link error,compiling 编译 linking 链接 preprocess 预处理 translation unity 编译单元任何常量在编译时会被直接算得出, 如代码中5*2, 编译时会直接显示10编译和链接是两个不同的阶段, 报的错误也是独立的, C开头的错误是编译阶段, LNK开头的错误是链接阶段。

weixin_65612492的博客 1074

跟着Cherno学习C++(一)——C++是如何工作的

C++基础语法从入门到精通,跟着Cherno学习C++

weixin_45813633的博客 1197

Cherno CPP学习笔记-03-高级特性

一方面,需要额外的内存来存储v表,这样我们就可以分配到正确的函数,包括基类中要有一个成员指针,指向v表;虚函数表就是一个表,包含所有基类中所有虚函数的映射,这样我们在运行时可以将他们映射到正确的覆写(override)函数。可见性是属于面向对象编程的概念,它指的是类的某些成员或方法实际上有多可见:谁能看见他们、谁能调用他们、谁能使用它们;如果我们开始有一个数据类型,然后有另一种类型,在两者之间,C++允许隐式进行转换,而不需要用cast做强制转换。如果对象很大,或者想要显式地控制对象地生存期,在堆上创建。

qq_45555061的博客 837

Cherno的Cpp教程笔记022:C++的智能指针

智能指针

ResumeProject的博客 340

Cherno c++教程个人笔记(持续更新)

自用,便于复习。

DaMiDYD的博客 928
上一篇: Linux驱动进化:传统模型、设备总线驱动模型、设备树
下一篇: 设备树的引入和内核对设备树的处理
ZHU~.
博客等级 码龄7年 193粉丝 24原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值