C++基础
叫我东方小巴黎
这个作者很懒,什么都没留下…
展开
-
【C++基础】C++除法陷阱
计算2个double类型相除结果,如61/387,应得0.15*****检查发现“/” 运算会自动将结果四舍五入,直接用“/”计算结果却为0。原创 2023-03-23 16:39:04 · 387 阅读 · 0 评论 -
【C++基础】for循环中尽量不要用浮点数double/float
中的值是0-01111111110-1110011001100110011001100110011001100110011001100110通过在浮点计算器中输入它得到的值,0.95000016然后添加0.05到该值上就可以了1.0。当使用浮点值时,并不是每个值都可以精确表示,0.95+0.05 > 1因为0.95不能用一个double值精确表示。这就是为什么你不应该在循环中使用浮点数(或者更一般地说,将浮点计算的结果与一个精确值进行比较)。看看维基百科对浮点精度的看法。原创 2023-02-08 00:31:26 · 1155 阅读 · 0 评论 -
【C++基础】delete 与 delete[] 区别
此种情况中的释放效果相同,原因在于:分配简单类型内存时,内存大小已经确定,系统可以记忆并且进行管理,在析构时,系统并不会调用析构函数, 它直接通过指针可以获取实际分配的内存空间,哪怕是一个数组内存空间(在分配过程中 系统会记录分配内存的大小等信息,此信息保存在结构体_CrtMemBlockHeader中, 具体情况可参看VC安装目录下CRT\SRC\DBGDEL.cpp)但是如果是C++ 对象数组就不同了!原创 2023-02-05 02:55:30 · 147 阅读 · 0 评论 -
【C++基础】函数返回数组
【代码】【C++基础】函数返回数组。原创 2023-02-05 02:52:48 · 414 阅读 · 0 评论 -
【C++基础】typedef struct关键字
typedef是类型定义的意思typedef struct 是为了使用这个结构体方便。原创 2023-01-23 02:45:01 · 1049 阅读 · 0 评论 -
【C++基础】指针基础
【代码】【C++基础】输出指针,&指针 *指针。原创 2022-11-19 22:02:22 · 848 阅读 · 0 评论 -
【C++】在堆中创建数组
由于我们刚才对pa进行了自加,这里用delete释放的时候就会出错,因为pa自加后就没有指向数组第一个元素的地址了,系统无法正确的释放我们在堆中创建的数组所占的内存空间。将pa申明为常指针后,我们就无法改变pa指针了,比如无法pa++;但是通常我们都不这样用,而是用数组的下标[]去访问数组元素。这样看上去,对pa指针自加后pa指针指向了数组的第二个元素,然后对第二个元素赋值为10,编译没有错,也能成功赋值。这样就在堆中创建了有10个元素的整型数组,然后把数组地址(即数组第一个元素的地址)赋给pa指针。原创 2022-09-16 09:05:37 · 1428 阅读 · 0 评论 -
【C++】enum class 域化枚举
1.enum class是类型安全的2.枚举定义将被限制在枚举作用域内,不能隐式转换为整数类型,但是可以强制转化为整数类型3.使用enum class必须带作用域名。https://blog.csdn.net/qq_38409301/article/details/121180318https://blog.csdn.net/qq_43331089/article/details/121655801.........原创 2022-06-22 10:02:07 · 416 阅读 · 0 评论 -
【C++】指针相关
指针相关原创 2022-06-18 15:04:19 · 166 阅读 · 0 评论 -
【C++】for循环中++i比i++性能好
在进行大量循环的时候++i的性能要比i++的性能好原创 2022-06-14 20:25:24 · 483 阅读 · 0 评论 -
【C++】override和final关键字
https://zhuanlan.zhihu.com/p/258383836今天我想谈谈override和final,这一对在C++11中不太引人注意的特性,相比于C++11其他特性而言也更简单。这两个特性都能让我们的程序在继承类和覆写虚函数时更安全,更清晰。你有没有像我一样遇到过这种情况:在子类中,本来你想覆写虚函数,结果虚函数却没有被正确地调用呢?或者更惨的是,你有时不得不去修改父类虚函数的声明。在所有的子类中查找重载的函数这件事可真的是很麻烦,而且墨菲定律告诉你:你永远会忘掉你搞错了的那一个子类。不管原创 2022-06-11 11:22:17 · 1766 阅读 · 0 评论 -
【C++】虚函数表、虚函数指针
虚函数表、虚指针 当一个类在实现的时候,如果存在一个或以上的虚函数时,那么这个类便会包含一张虚函数表。而当一个子类继承并重载了基类的虚函数时,它也会有自己的一张虚函数表。当我们在设计类的时候,如果把某个函数设置成虚函数时,也就表明我们希望子类在继承的时候能够有自己的实现方式;如果我们明确这个类不会被继承,那么就不应该有虚函数的出现。下面是某个基类A的实现:class A {public: virtual void vfunc1(); virtual void vfunc2();原创 2022-03-26 19:25:30 · 1060 阅读 · 0 评论 -
【C++】基类析构函数要写成虚函数
如果不写成虚函数Base* p = new Derived();delete p;只会调用~Base()不会调用~Derived()析构函数中不可能发生多态行为在析构函数执行时,虚函数表指针已经被销毁https://blog.csdn.net/lsy0607/article/details/101720134(1)构造函数中不可能发生多态行为,在构造函数执行时,虚函数表指针未被正确初始化。(2)析构函数中不可能发生多态行为,在析构函数执行时,虚函数表指针已经被销毁。https://b原创 2022-03-26 19:10:03 · 512 阅读 · 0 评论 -
【C++】swtich和case语句中,定义变量要加花括号
系统不允许我们在case中定义一个变量,原因是我们在一个case中定义的变量,假如在另一个case中被使用就会出现错误,因为一般来说switch语句中的case只能被执行一个switch是我们做条件选择时,经常用到的一个语句。一直以来对于他的使用相信大家也都是得心应手,前几天在linux下写一个c++程序时遇到了这样的一个问题,请看例子:#include<iostream>using namespace std;int main(){ int i; co原创 2022-03-24 17:17:02 · 2787 阅读 · 0 评论 -
【C++】头文件中写类的实现出现函数重复定义的问题
先来做一个实验,你在一个头文件中定义一个类,然后把内中的一个函数的实现写在这个头文件当中。//A_test.h#ifndefine _A_TEST_#define _A_TEST_class A{void test();};void A::test(){}#endif//A_test.cpp#include A_test.h//B_test.cpp#include A_test.h//C_test.cpp#include A_test.h然后在两个B.cpp原创 2022-03-23 10:12:22 · 2334 阅读 · 0 评论 -
【C++】抽象类
包含纯虚函数的类称为抽象类抽象类中可有非抽象方法原创 2022-03-20 15:13:35 · 675 阅读 · 0 评论 -
【C++】虚函数、纯虚函数、抽象类,派生类虚函数加不加virtual
定义一个函数为虚函数,不代表函数为不被实现的函数。定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。定义一个函数为纯虚函数,才代表函数没有被实现https://www.runoob.com/w3cnote/cpp-virtual-function.htmlc++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。因此,在子类重新声明该虚函数时,可以加,也可以不加,但习惯上每一层声明函数时都加virtual,使程序更加清晰......原创 2022-03-15 10:58:10 · 2783 阅读 · 0 评论 -
【C++】overrrid关键字
override 关键字作用:在成员函数声明或定义中, override 确保该函数为虚函数并覆写来自基类的虚函数。位置:函数调用运算符之后,函数体或纯虚函数标识 “= 0” 之前。使用以后有以下好处:1.可以当注释用,方便阅读2.告诉阅读你代码的人,这是方法的复写3.编译器可以给你验证 override 对应的方法名是否是你父类中所有的,如果没有则报错.override 使用举例如果你想重写父类的方法,比如toString()方法:cpp#if 1public :virtual S原创 2022-03-01 14:21:08 · 980 阅读 · 0 评论 -
【C++】explicit关键字
C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生,声明为explicit的构造函数不能在隐式转换中使用。C++中, 一个参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造函数), 承担了两个角色。1 是个构造;2 是个默认且隐含的类型转换操作符。所以, 有时候在我们写下如 AAA = XXX, 这样的代码, 且恰好XXX的类型正好是AAA单参数构造器的参数类型, 这时候编译器就自动调用这个构造器, 创建一个AAA的对象。这样看起来好象很酷,原创 2022-02-28 19:25:14 · 74 阅读 · 0 评论 -
C++:派生类的构造函数
基类构造函数不能继承声明派生类时,派生类没把基类构造函数继承过来,因此,对继承过来的基类成员初始化工作也要由派生类的构造函数承担。设计派生类构造函数时,不仅考虑派生类所增成员初始化,还应考虑基类数据成员初始化。解决方法:执行派生类构造时,调用基类构造...原创 2021-12-26 16:50:12 · 680 阅读 · 0 评论 -
C++:public/private/protected继承权限
继承改变的是,基类公共/保护的权限,基类私有成员永远不可见/受保护公有继承:基类公共/保护,在派生类共有。私有,在基类私有私有继承:基类公共/保护,在派生类私有。私有,在基类私有保护继承 :基类公共/保护,在派生类保护。私有,在基类私有...原创 2021-11-20 16:15:44 · 630 阅读 · 0 评论 -
C++:排序算法
排序算法冒泡排序冒泡排序1. 排序思想基本思想: 冒泡排序,类似于水中冒泡,较大的数沉下去,较小的数慢慢冒起来,假设从小到大,即为较大的数慢慢往后排,较小的数慢慢往前排。直观表达,每一趟遍历,将一个最大的数移到序列末尾2. 算法描述比较相邻的元素,如果前一个比后一个大,交换之。第一趟排序第1个和第2个一对,比较与交换,随后第2个和第3个一对比较交换,这样直到倒数第2个和最后1个,将最大的数移动到最后一位。第二趟将第二大的数移动至倒数第二位3. 复杂度时间复杂度: O(n²)空原创 2021-09-14 10:08:05 · 64 阅读 · 0 评论 -
C++:字符数组
字符数组1. 字符数组的定义和初始化2. 字符数组的赋值和引用3. 字符串和字符串结束标志1. 字符数组的定义和初始化char c[3];c[0] = 'a';c[1] = 'b';c[2] = 'c';等价于char c[3] = {'a','b','c'};如果花括号中提供的初值个数大于数组长度,语法错误如果花括号中提供的初值个数小于数组长度,字符赋给数组中前面的那些元素,其余元素自动定位空字符(’\0’),如果花括号中提供的初值个数等于预定数组长度,定义时可以省略数组长度,数组原创 2021-09-13 19:17:56 · 8029 阅读 · 0 评论 -
C++:结构体名字是一个指向结构体的起始位置的指针
它是一个指向结构体的起始位置的指针原创 2021-09-01 01:55:23 · 550 阅读 · 0 评论 -
C++:输入输出流
输入输出流概念注意概念在内存中为每一个数据流开辟一个内存缓冲区,用来存放流中的数据cout<<(插入运算符号)先将输出数据送到程序中输出缓冲区直到缓冲区满或遇到endl,将缓冲区中全部数据送到显示器显示cin>>(提取运算符号)键盘输入先放在键盘缓存区按回车键,键盘缓存区数据输出到程序中的输入缓冲区,形成cin流,然后用提取运算符,>>从输入缓冲去提取数据给程序中有关变量注意cout流对象在内存中开辟了一个缓冲区,存放流中数据,向cout插入一个原创 2021-08-02 11:26:11 · 71 阅读 · 0 评论 -
类型转换函数
类型转换函数1. 作用2. 格式3. 注意4. Demo1. 作用类对象转换成另一类型数据2. 格式operator 类型名() {实现转换语句}3. 注意函数名前不能指定函数类型,函数没有参数返回值类型,由函数名中指定的类型名来确定(测试不return也行,但只要返回类型必须和指定类型名一致,不然编译报错)只能作为成员函数,因为转换的主体是本类的对象形式和重载运算符类似,只是被重载的是类型名。如重载的是double,double除了原来的含义,获得新含义,将一个类对象转换为doub原创 2021-07-29 18:25:46 · 1617 阅读 · 0 评论 -
转换构造函数
功能:将其它类型数据转换为一个类对象注意:只有一个形参原因:如果有多个参数的话,不知道把那个参数转换为类对象Demo:#include <iostream>#include "Test2.h"#include <string.h>using namespace std;class B {public: int Bnum; string Bstring; B(int,string);};B::B(int Bnum,string Bstring) {.原创 2021-07-29 16:49:28 · 93 阅读 · 0 评论 -
重载流插入运算符和流提取运算符
重载流插入运算符和流提取运算符1. 运算符介绍2. 声明格式3. 注意3. Demo1. 运算符介绍1)流插入运算符 <<2)流提取运算符 >>int i;cin >> i; //从输入流提取一个整数赋给变量i2. 声明格式istream& operator >> (istream&, 自定义类&);ostream& operator << (ostream&, 自定义类&);3原创 2021-07-29 14:44:42 · 1577 阅读 · 0 评论 -
C++:字符串与指针
C++中三种方法访问一个字符串字符数组存放一个字符串char c1[] = "ab";cout << c1; // abcout << *s1 // ac1是数组名,代表字符数组首元素地址,输出时从c1指向的字符开始,逐个输出字符,知道遇到’\0’为止。字符串变量存放字符串string s1 = "ab";cout<<s1; //ab字符指针指向一个字符串char c1[] = "ab";char *p = c1; // same a原创 2021-07-28 15:30:10 · 414 阅读 · 0 评论 -
C++:struct结构体
嵌套结构体初始化内部结构体,初始化时,用大括号“{ }”扩起来即可struct St1 { int num1; string str1;};struct St2 { int num2; string str2; St1 st1;};int main() { St2 st2 = {1,"aa",{2,"bb"}}; cout<<st2.num2<<endl<<st2.str2<<endl<<st2.st1.num1&.原创 2021-06-30 18:57:15 · 502 阅读 · 0 评论 -
字符数组可以初始化,不能赋值,能strcpy的原因
能初始化不能赋值原创 2021-06-28 18:27:19 · 1012 阅读 · 0 评论 -
C++: template类模板
类模板中Compare<numtype> 是一个整体 ,是一个带参数的类。声明对象Compare<numtype> object;声明函数template <class numtype>numtype Compare<numtype> ::function() {}demo#include <iostream>#include <stdint.h>using namespace std;templ原创 2021-06-26 16:57:34 · 179 阅读 · 2 评论 -
左移8位与的意义
int main() { uint8_t data[2]; uint16_t version; data[0] = 0x01; version = data[0] << 8; printf("%04x",data[0]); //输出 0100}int main() { uint8_t data[2]; uint16_t version; data[0] = 0x01; data[1] = 0x10; version = data[0] << 8 | d原创 2021-06-22 11:22:55 · 11882 阅读 · 3 评论 -
C++:常对象、常成员变量、常成员函数、指向对象的常指针、指向常对象的指针、对象的常引用
C++中常对象、常成员函数、常成员变量常对象常数据成员常成员函数常对象类名 const 对象名const 类名 对象名所有成员的值都不能修改,(所有数据成员都是常数据成员)(非要改变成员用mutable标记成员变量)const对象只能调用const成员函数不能调用非const函数,但类中可能有非const函数,但不能用必须要有初值常数据成员必须用参数初始化表初始化,因为其不能赋值能被常/非常成员函数引用常成员函数void f1() const //const加后面原创 2021-05-31 17:44:40 · 1084 阅读 · 0 评论 -
#include<>和#include““的区别
一般来说#include <> 的查找位置是 标准库头文件所在目录。#include “” 的查找位置是 当前源文件所在目录。不过这些都可由编译器调用参数等配置更改。而""首先在当前目录下寻找,如果找不到,再到系统目录中寻找。这个用于include自定义的头文件,让系统优先使用当前目录中定义的。若 #include “” 查找成功,则遮蔽 #include <> 所能找到的同名文件;否则再按照 #include <> 的方式查找文件。另外标准库头文件都放在原创 2021-05-27 17:28:10 · 244 阅读 · 0 评论 -
作用域限定符::前没作用域的意义
看到一段代码: virtual void close() { if (mPipe[0] > 0) { ::close(mPipe[0]); mPipe[0] = -1; } }::close 这里是调用标准的写函数, 不加全局域符号也可以啊?后来发现这里是成员函数名和标准函数完全一样了, 所以必须加以区分. 否则默认调用成员函数.void printf();int main() {::print原创 2021-05-26 18:39:05 · 762 阅读 · 0 评论 -
struct和class的区别
struct 存在的原因也有为了兼容c的写法struct和class基本类似区别struct不作声明默认权限为publicclass不作声明默认权限为private如果没有多态和虚拟继承,在C++中,struct和class的存取效率完全相同,存取class的数据成员与非虚函数效率和struct完全相同,不管该数据成员是定义在基类还是派生类。class的数据成员在内存中的布局不一定是数据成员的声明顺序,C++只保证处于同一个access section的数据成员按照声明顺序排列在C++中,c.原创 2021-05-26 17:44:52 · 299 阅读 · 0 评论 -
C++ 值传递、指针传递、引用传递
C++ 值传递、指针传递、引用传递1. 值传递2. 指针传递3. 引用传递4.其它1. 引用传递和指针传递区别2. 引用传递的优点java只有值传递: java是按值调用(值传递)还是按引用调用(引用调用)而C++有三种:1. 值传递 实参和形参都是变量名 这是传给形参的是变量的值,传递是单向的。如果执行函数期间函数形参数值发生变化,不回传给实参,因为在调用函数时候形参和实参不是同一个存储单元。调用时,将实参的值传递对应的形参,即为值传递。由于形参有自己独立的存储空间,又作为函数的局部变量使用原创 2021-05-26 11:39:12 · 347 阅读 · 5 评论 -
C++常用函数
C++常用函数fwritefwritesize_t fwrite(const void* buffer,size_t size,size_t count,FILE* stream); 注意:这个函数以二进制形式对文件进行操作,不局限于文本文件 返回值:返回实际写入的数据块数目 (1)buffer:是一个指针,对fwrite来说,是要输出数据的地址。 (2)size:要写入内容的单字节数; (3)count:要进行写入size字节的数据项的个数; (4)stream:目原创 2021-04-26 17:56:13 · 80 阅读 · 0 评论 -
指针变量做函数参数
数组名做函数参数,传递的是数组首元素地址。指针变量做函数形参,同样可接受从实参传来的首元素的地址。C++编译系统将形参数组名一律作为指针变量处理。void f1(int a[],int n);void f1(int *a,int n);以上两种写法完全等价。可以理解为一个形参数组,从实参数组哪里得到起始地址,因此形参数组与实参数组共占一段内存单元,调用函数期间,如改变了形参数组的值,也就改变了实参数组的值void f1(int *b); // b[]int main() { int a原创 2021-04-22 02:08:29 · 181 阅读 · 0 评论