Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >栈内存 ,堆内存区别 C++ 动态内存 == 与equal区别 复合函数奇偶性 三角函数转换公式: 虚函数和纯虚函数: C++ 中的运算符重载 数据封装,数据抽象 C++ 接口(抽象类

栈内存 ,堆内存区别 C++ 动态内存 == 与equal区别 复合函数奇偶性 三角函数转换公式: 虚函数和纯虚函数: C++ 中的运算符重载 数据封装,数据抽象 C++ 接口(抽象类

作者头像
zhangjiqun
发布于 2024-12-16 08:55:20
发布于 2024-12-16 08:55:20
730
举报
文章被收录于专栏:计算机工具计算机工具

栈内存 ,堆内存区别

栈内存:在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

堆内存:用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。

C++ 动态内存

栈:在函数内部声明的所有变量都将占用栈内存。 堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。 很多时候,您无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。

在 C++ 中,您可以使用特殊的运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。这种运算符即 new 运算符。

如果您不再需要动态分配的内存空间,可以使用 delete 运算符,删除之前由 new 运算符分配的内存。

new 和 delete 运算符

== 与equal区别

“equal”先比较地址,不相等,再比较指针最终指向的是数值,

"=="比较的是对象地址。这是根本的区别。

复合函数奇偶性

由两个函数复合而成的复合函数

当里层的函数是偶函数时,复合函数的偶函数,不论外层是怎样的函数;当里层的函数是奇函数、外层的函数也是奇函数时,复合函数是奇函数,当里层的函数是奇函数、外层的函数是偶函数时,复合函数是偶函数。

总结:只有奇奇是奇奇,别的都是偶。

三角函数转换公式:

sin^2(x)+cos^2(x)=1;

1+tan^2(x)=sec^2(x);

1+cot^2(x)=csc^2(x);

cos(2x)=1-2sin^2 (x) = 2cos^2x-1 = cos^2(x)-sin^2(x);

(tan(x))'=sec^2(x) = 1+tan^2(x);

sin(2x)=2sin(x)cos(x);

虚函数和纯虚函数:

就是java中的抽象,纯虚函数只有声明没有具体实现就是空方法,在子类中必须重新写,虚函数就是在积累中写了有实现。他们都得用关键字 virtual 声明的函数 1. 虚函数和纯虚函数可以定义在同一个类(class)中,含有纯虚函数的类被称为抽象类(abstract class),而只含有虚函数的类(class)不能被称为抽象类(abstract class)。

2. 虚函数可以被直接使用,也可以被子类(sub class)重载以后以多态的形式调用,而纯虚函数必须在子类(sub class)中实现该函数才可以使用,因为纯虚函数在基类(base class)只有声明而没有定义

3. 虚函数和纯虚函数都可以在子类(sub class)中被重载,以多态的形式被调用。

4. 虚函数和纯虚函数通常存在于抽象基类(abstract base class -ABC)之中,被继承的子类重载,目的是提供一个统一的接口。

C++ 中的运算符重载

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。

Box operator+(const Box&); 声明加法运算符用于把两个 Box 对象相加,返回最终的 Box 对象。大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。如果我们定义上面的函数为类的非成员函数,那么我们需要为每次操作传递两个参数,如下所示:

Box operator+(const Box&, const Box&);

数据封装,数据抽象

数据封装是一种把数据和操作数据的函数捆绑在一起的机制

数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制

C++ 接口(抽象类):

如果类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类。纯虚函数是通过在声明中使用 "= 0" 来指定的,如下所示:

class Box { public: // 纯虚函数

virtual double getVolume() = 0;

#和##运算符

#是预处理?是的,你可以这么认为。那怎么用它呢? 别急,先看下面例子:

#define SQR(x) printf("The square of x is %d.\n", ((x)*(x)));

The square of x is 64.

注意到没有,引号中的字符 x 被当作普通文本来处理,而不是被当作一个可以被替换的语言符号。

假如你确实希望在字符串中包含宏参数,那我们就可以使用“#” ,它可以把语言符号转

化为字符串。上面的例子改一改:

#define SQR(x) printf("The square of "#x" is %d.\n", ((x)*(x)));

The square of 8 is 64.

##运算符可以用于宏函数的替换部分。这个运算符把两个语言符号组合成单个语言符号。看例子:

#define XNAME(n) x ## n

则会被展开成这样:

x8

也就是说,##就是个粘合剂,将前后两部分粘合起来。

const,volatile ,restrict 解释

const 类型的对象在程序执行期间不能被修改改变。 volatile 修饰符 volatile 告诉编译器不需要优化volatile声明的变量,让程序可以直接从内存中读取变量。对于一般的变量编译器会对变量进行优化,将内存中的变量值放在寄存器中以加快读写效率。 restrict 由 restrict 修饰的指针是唯一一种访问它所指向的对象的方式。只有 C99 增加了新的类型限定符 restrict。

总结排序:认准1.数组规模。2.数组是否基本有序3.是否要求稳定

记住:冒泡以及归并是稳定的。

快排不稳定,基本就能解决问题

(1)若n较小(如n≤50),可采用直接插入或直接选择排序。  当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。 (2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜; (3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。  快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;  堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。  若要求排序稳定,则可选用归并排序。但本章介绍的从单个记录起进行两两归并的 排序算法并不值得提倡,通常可以将它和直接插入排序结合在一起使用。先利用直接插入排序求得较长的有序子文件,然后再两两归并之。因为直接插入排序是稳定 的,所以改进后的归并排序仍是稳定的。

计算机原理中的位向量表示集合:

a=[01101001]表示{0,3,5,6} b=[01010101]表示{0,2,4,6} 最终a&b={01000001}={0,6}

以题目的例子来讲,a=[01101001],从右边数起,第0、3、5、6位是1,所以就表示了0、3、5、6这4个数,b的话同理,对应的是0、2、4、6这4个数。之后的并集就不用再说了吧。

结构体解释:

typedef struct LNode{ //此行的LNode是一个结构标签 ElemType data; struct LNode *next; }LNode,*LinkList; //此行的LNode是结构体struct LNode的一个别名 //*LinkList也是结构体struct LNode的一个别名 //换言之LinkList是结构体struct LNode类型的指针的别名 //也就是说 struct LNode *p;这条语句等同于LinkList p;使用:p->date

逗号运算符和逗号表达式

3+5,6+8 上式称为逗号表达式。逗号表达式的一般形式为:表达式1,表达式2

逗号表达式的求解过程是:先求解表达式1,再求解表达式2。整个逗号表达式的值是表达式2的值

switch的default问题。不同位置结果不同

#include <iostream> using namespace std; int main() { int a=1,b=2,c=3,d=4,y=10; switch(y){ case 1:a++;break; default:d=1; case 2:b++;break;//b是可以跑进去的 case 4:c++;break; } cout << a<<b<<c<<d<< endl; return 0; }

结果:

1331

a[i++] =1;//先a[i] i再加加

#include <iostream> using namespace std; const int MAX=20;

int main() { int i=0; int a[22]; a[++i] =1; //先i加加再a[i] cout<<a[0]<<endl; cout<<a[1]<<endl; cout<<i<<endl; return 0; }

结果:

0 1 1

p是指针,p++就是指针的移位

cout<<*p:就是取出指针当前指向元素cout<<p:就是这个指针指向的全部字符;

例子:

#include <iostream> using namespace std; int main() {

char str []="Orange or Apple?"; char *p=str; cout<<p<<endl;//输出全部str cout <<p++<<endl;//指针you移位一下 cout<<*p<<endl; //输出指针指向的元素 cout<<p<<endl;//输出指针后面的元素 return 0; }

结果:

Orange or Apple? Orange or Apple? r range or Apple?

补充*++p,++*p,*p++,*(p++):

int arr[5] = { 1,3,5,7,9 };

int *p = arr;

*++p:p先自+,然后*p,最终为3

++*p:先*p,即arr[0]=1,然后再++,最终为2

*p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]

(*p)++:先*p,即arr[0]=1,然后1++,该语句执行完毕后arr[0] =2

*(p++):效果等同于*p++

纯虚函数,虚函数,友原函数,内联函数

1、纯虚函数声明如下: virtual void funtion1()=0; 纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。包含纯虚函数的类是抽象类,抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或引用。 2、虚函数声明如下:virtual ReturnType FunctionName(Parameter);虚函数必须实现

实际上我个人认为纯虚函数的引入,是出于两个目的 1、为了安全,因为避免任何需要明确但是因为不小心而导致的未知的结果,提醒子类去做应做的实现。 2、为了效率,不是程序执行的效率,而是为了编码的效率。

友元函数:可以访问类的私有数据成员和私有函数。 友元函数声明有friend,但定义不需要。

class persion{ public: persion(char *pn); //友元函数; friend void setweigth(persion &p,int h);//友元函数可以访问类中的私有成员和其他数据,但是访问不可直接使用数据成员,需要通过对对象进行引用。 void disp(); //类成员函数 private: char name[20]; int weigth,age; }; persion::persion(char *pn) //构造函数 { strcpy(name,pn); weigth=0; } void persion::disp() { cout<<name<<"--"<<weigth<<endl; } //友元函数的具体实现:这里没有类限定例如 (perion::setweigth)这种形式,这里可以与上面的disp()做个对比,一个属于类的成员,有限定,不属于类的成员函数,没有加限定。 void setweigth(persion &pn,int w) { strcpy(pn.name,pn);//实现字符串复制 pn.weigth=w; //私有成员数据赋值 }

友元不是成员函数,只有成员函数才可以是虚拟的,因此友元不能是虚拟函数。但可以通过让友元函数调用虚拟成员函数来解决友元的虚拟问题。

析构函数(destructor) 与构造函数相反,当对象结束其生命周期,如对象所在的函数已调用完毕时,系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。 析构函数应当是虚函数,将调用相应对象类型的析构函数,因此,如果指针指向的是子类对象,将调用子类的析构函数,然后自动调用基类的析构函数。

double 和 float:double表示范围更大,小数点后的精度更精确

::是运算符中等级最高的

它分为三种:

1)global scope(全局作用域符),用法(::name)

2)class scope(类作用域符),用法(class::name)

3)namespace scope(命名空间作用域符),用法(namespace::name)

例子:

#include <iostream> using namespace std; int a=100; int main() { int a=10; cout <<::a<<endl; return 0; }

结果:

100

#include <iostream> using namespace std; int main () { int var = 20; // 实际变量的声明 int *ip; // 指针变量的声明 ip = &var; // 在指针变量中存储 var 的地址 cout << "Value of var variable: "; cout << var << endl; // 输出在指针变量中存储的地址 cout << "Address stored in ip variable: "; cout << ip << endl; // 访问指针中地址的值 cout << "Value of *ip variable: "; cout << *ip << endl; return 0; }

代码结果:

Value of var variable: 20 Address stored in ip variable: 0x7fff5bfda1d8 Value of *ip variable: 20 ————————————————

const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间。

static表示的是静态的。类的静态成员函数、静态成员变量是和类相关的,而不是和类的具体对象相关的。即使没有具体对象,也能调用类的静态成员函数和成员变量。一般类的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件中。 ————————————————

inline,内联函数

inline int max(int a, int b) { return (a>b)? a : b; }

当编译器发现某段代码在调用一个内联函数时,它不是去调用该函数,而是将该函数的代码,整段插入到当前位置。这样做的好处是省去了调用的过程,加快程序运行速度。 1.在内联函数内不允许使用循环语句和开关语句;2.内联函数的定义必须出现在内联函数第一次调用之前;3.类结构中所在的类说明内部定义的函数是内联函数。

cout<<'s'<<setw(8)<<'a'<<endl; 则在屏幕显示 s a //s与a之间有7个空格

指针数组定义 int *p[n];

int a[3][4]这个无需多说,就是一个二维数组。 int (*p)[4]就相当于int p[][4],它就是一个二维数组的指针,可以指向一个第二维度为4的二维数组。而a就是这样的数组,因而下面是合法的。 p=a; int *p[3]是指针数组。说白了,就是定义了三个指针,分别为p[0],p[1],p[2]。可以将他们单独拿来使用。 int a1,a2,a3; p[0]=&a1; p[1]=&a2; p[2]=&a3;

优先级:()>[]>* ————————————————

∫secxdx =∫secx(secx+tanx)dx/(secx+tanx) =∫(sec²x+tanxsecx)dx/(secx+tanx) =∫d(tanx+secx)/(secx+tanx) =ln|secx+tanx|+C

原题应是: ∫cscxdx=? ∫cscxdx=∫(1/sinx)dx =∫(1/(2sin(x/2)cos(x/2)))dx =∫(1/(tan(x/2))dtan(x/2) =ln|tan(x/2)|+C

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
抽象类纯虚函数与虚析构
纯虚函数,一般是在设计一个基类时使用的,它将接口函数设置为纯虚函数后,只提供子类去继承并实现,以形成多态,除此以外不提供任何其他功能,我们称这种类为抽象类(abstract)。
我与梦想有个约会
2023/10/20
2310
抽象类纯虚函数与虚析构
C++纯虚函数与抽象类
为什么说虚函数是C++最重要的特性之一呢,因为虚函数承载着C++中动态联编的作用,也即多态,可以让程序在运行时选择合适的成员函数。虚函数必须是类的非静态成员函数(且非构造函数),其访问权限是public。那么: (1)为什么类的静态成员函数不能为虚函数? 如果定义为虚函数,那么它就是动态绑定的,也就是在派生类中可以被覆盖的,这与静态成员函数的定义(在内存中只有一份拷贝,通过类名或对象引用访问静态成员)本身就是相矛盾的。
恋喵大鲤鱼
2018/09/27
1.6K0
C++基础知识复习
就算using namespace xxx了一个命名空间,我们仍然可以通过xxx::来使用其它的命名空间。
半生瓜的blog
2023/05/12
5850
C++基础知识复习
C++继承、虚函数、RTTI、友元类、异常处理
前面讲到c++的继承是子类在继承时声明继承的权限,之前描述有点不够准确。以下时书中提及的能继承的成员。
歪歪梯
2020/08/17
8300
《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)「建议收藏」
面向对象程序设计(Object-Oriented Programming,OOP)是一种新的程序设计范型。程序设计范型是指设计程序的规范、模型和风格,它是一类程序设计语言的基础。
全栈程序员站长
2022/09/10
3.5K0
《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)「建议收藏」
什么?C/C++面试过不了?因为你还没看过这个!
(为了方便记忆可以想成)被 const 修饰(在 const 后面)的值不可改变,如下文使用例子中的 p2、p3。
杨源鑫
2020/06/04
3.8K0
【c++】多态(多态的概念及实现、虚函数重写、纯虚函数和抽象类、虚函数表、多态的实现过程)
本篇文章是继继承之后,博主跟大家介绍面向对象三大特性的最后一个——多态。
ephemerals__
2024/12/25
4950
【c++】多态(多态的概念及实现、虚函数重写、纯虚函数和抽象类、虚函数表、多态的实现过程)
从零开始学C++之运算符重载(四):类型转换运算符、*运算符重载、->运算符重载、operator new 和 operator delete
该文摘要总结
s1mba
2017/12/28
7200
从零开始学C++之运算符重载(四):类型转换运算符、*运算符重载、->运算符重载、operator new 和 operator delete
闭关多日,整理一份C++中那些重要又容易忽视的细节
内联函数,都知道是什么嘛,就不多解释了,用这个开头,因为它够简单,又有足够的争议性。 有的人喜欢用内联函数,有的人不喜欢用,我嘛,无所谓,什么时候想起来就什么时候用,或者在代码审计的时候会去调整一部分函数为内联函数。
看、未来
2021/09/18
6310
C/C++面试常问题集(2)
C++中,并不是所有的成员函数都能被子类继承,有三类成员函数不能被子类继承,分别是:构造函数(包括拷贝构造)、析构函数、赋值运算符重载函数。
_咯噔_
2022/03/04
1.2K0
C++查缺补漏
本文总结了几乎所有不易理解或是容易忘记的C++知识,可作为手册查阅,内容参考自清华大学郑莉教授的C++课程。
luxuantao
2021/02/20
2.6K0
大学C++课程提炼概括【C++笔记】
如果未写明限制幅(public: private: protected: )则默认为私有
来杯Sherry
2023/05/25
4140
C++面向对象编程一些拾遗
虽然说是拾遗,但是这里有一大部分是我以前没有看过的,简书的markdown不支持生成目录,可能需要手动来一个了。
和蔼的zhxing
2018/09/04
7190
C++面向对象编程一些拾遗
C++关键知识点梳理
类似于函数,但是其()中的参数不是真的函数参数,在编译器进行宏展开时对()里的参数进行"一对一"的替换。
liddytang
2023/03/08
1K0
【C++】自学终极笔记
2. main()函数的返回类型可以是任意的数据类型,而且是唯一一个非void型【 即void main()】可以不用return,因为main()由操作系统直接控制,不能被其他函数调用。
SarPro
2024/02/20
2700
【C++】自学终极笔记
C++运算符重载详解
C++语言的一个很有意思的特性就是除了支持函数重载外还支持运算符重载,原因就是在C++看来运算符也算是一种函数。比如一个 a + b 的加法表达式也可以用函数的形式:operator + (a, b)来表达。这里的operator +代表的就是加法函数。高级语言中的表达式和数学表达式非常相似,在一定的程度上通过运算符来描述表达式会比通过函数来描述表达式更加利于理解和阅读。一般情况下在重载某个运算符的实现时最好要和运算符本身的数学表示意义相似,当然你也可以完全实现一个和运算符本身意义无关的功能或者相反的功能(比如对某个+运算符实现为相减)。运算符函数和类的成员函数以及普通函数一样,同样可分为类运算符和普通运算符。要定义一个运算符函数总是按如下的格式来定义和申明:
欧阳大哥2013
2018/08/22
1.5K0
C++ 重载运算符 继承 多态 (超详细)
(1)声明与定义格式 一般是类内声明,类外定义,虽然可以在类内定义,但 写前面堆一堆不好看!!! 类内声明:
风骨散人Chiam
2020/10/28
1.2K0
C++ 重载运算符 继承  多态 (超详细)
【C++】运算符重载案例 - 字符串类 ⑤ ( 重载 大于 > 运算符 | 重载 小于 < 运算符 | 重载 右移 >> 运算符 - 使用全局函数重载 | 代码示例 )
左移 << 操作符 cout << s << endl , 是将 s 对象输出到 cout 标准输出流中 ;
韩曙亮
2023/10/15
6360
C++进阶:详解多态(多态、虚函数、抽象类以及虚函数原理详解)
注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后基类的虚函数被继承后在派生类依旧保持虚函数属性)但是该种写法不规范,大家还是少用为好。
是Nero哦
2024/03/17
6330
C++进阶:详解多态(多态、虚函数、抽象类以及虚函数原理详解)
C++学习——虚函数与纯虚函数
若要访问派生类中相同名字的函数,必须将基类中的同名函数定义为 虚函数,这样,将不同的派生类对象的地址赋给基类的指针变量后, 就可以动态地根据这种赋值语句调用不同类中的函数。
全栈程序员站长
2022/09/23
4.1K0
C++学习——虚函数与纯虚函数
推荐阅读
相关推荐
抽象类纯虚函数与虚析构
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档