牛客微信推送的C++笔记:2016-12-12   14:23:26

1.C++不仅支持面向对象,也可以像C一样支持面向过程.

2.OOP三大特性:封装 继承 多态

3.函数重载依据:函数类型and形参个数,返回类型不能作为依据

4.常成员函数是指通过函数获得成员的值,不一定用const修饰返回值.

在程序设计中我们会经常调用函数,调用函数就会涉及参数的问题,那么在形参列表中const形参与非const形参对传递过来的实参有什么要求呢?

先来看一个简单的例子:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. void print_str(const string s)
  5. {
  6. cout<<s<<endl;
  7. }
  8. int main()
  9. {
  10. print_str("hello world");
  11. return 0;
  12. }

毫无疑问,const实参传递给const形参,正确调用函数,如果你将第4行代码中的const去掉,也能得到正确的结果。那么在去掉const的基础上将形参变为引用形参,会出现什么样的结果呢?看下面的代码:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. void print_str( string & s)
  5. {
  6. cout<<s<<endl;
  7. }
  8. int main()
  9. {
  10. print_str("hello world");
  11. return 0;
  12. }

发现编译不通过,如果在第4行的string前加上一个const,就会通过编译。进一步研究我们会发现指针形参与引用形参会出现类似的情况。普通形参加不加const限定符对实参没有影响,引用形参和指针形参前面没有const限定符时,实参必须是非const的,而前面有const限定符时对实参也没有什么影响。

为什么会出现这种情况?

原因在于实参的传递方式不同,函数中的形参是普通形参的时,函数只是操纵的实参的副本,而无法去修改实参,实参会想,你形参反正改变不了我的值,那么你有没有const还有什么意义吗?引用形参和指针形参就下不同了,函数是对实参直接操纵,没有const的形参时实参的值是可以改变的,这种情况下怎能用函数来操纵const实参呢。我一直这样记忆:“对于变量的约束,允许加强,当绝对不能削弱.....”例如:实参是const,那么形参如果是非const意味着可以在函数体中改变形参的值,使约束削弱了所以不行。对于使用&,自然也是这个道理。同样的,指针里面的const也是这个样子的,如果让非const指针指向了const对象的地址,那么必然是无法通过编译的,因为如果这样做了,意味着可以通过这个指针改变本该是const的值了,显然是使约束削弱了

5.引用就是取别名

6.名称空间防止命名冲突

7.private修饰函数和成员

8.inline内联函数

9.构造函数只负责初始化,不负责分配对象占用内存空间

10.构造函数能够重载,析构函数没有形参.

11.所有成员默认访问属性 private

12.引用类的目的:提供一个机制,实现从现实世界到程序世界的映射 提供代码重用性  数据封装

13.定义类 访问属性: 定义结束;

14.指针无论类型4字节

15.this指针是数据区中的数据和代码区中的函数连接的纽带,this指针作用于作用域的类内部 this指针作为非静态成员函数的隐含形参,编译器自动添加。

举个栗子:

dataSetMonth(9);<=>SetMonth(&date,9);

返回对象类本身

return *this;

当参数与成员名相同时,不能用n=n,需用this->n=n;

this指针实例:

class Point
{
int x, y;
public:
Point(int a, int b)
{
x = a;
y = b;
}
void MovePoint(int a, int b)
{
x += a;
y += b;
}
void print()
{
cout << "x=" << endl;
}
};
int main()
{
Point point1(, );
point1.MovePoint(, );
point1.print();
}

MovePoint函数中,x+=a <=> this->x+=a;x+=b <=> this->x+=b;

类的this指针的特点

(1) this只能在成员函数中使用 全局函数、静态函数都不能使用this 成员函数默认第一个参数为T* const this

举个栗子

class A
{
public:
int func(int p)
{
}
};

编译器认为是int func(A *const this,int p);

16.拷贝构造函数完成类对象的拷贝 CExample B=A; 系统为B对象分配了内存并完成了对A对象的复制

举个栗子

#include <iostream>
using namespace std; class CExample
{
private:
int a;
public:
CExample(int b)
{
a = b;
}
CExample(const CExample& C)
{
a = C.a;
}
void show()
{
cout << a << endl;
}
}; int main()
{
CExample A();
CExample B = A;
B.show();
return ;
}

CExample(const CExample& C)就是我们定义的拷贝构造函数.拷贝构造函数就是一种特殊的构造函数,函数的名称必须和类名称一致,必须的一个参数是本类型的引用变量.

17.圆形类的实现

#include <cmath>
#include "circle.h" Circle::Circle(double aX, double aY, double aR) :m_iX(aX), m_iY(aY), m_iRadius(aR){}
Circle::~Circle(){}
void Circle::setPos(double aX, double aY)
{
m_iX = aX;
m_iY = aY;
}
void Circle::getPos(double &rX, double &rY)const
{
rX = m_iX;
rY = m_iY;
}
double Circle::getRadius()const
{
return m_iRadius;
}
double Circle::getDist(const Circle & aRef)const
{
double x1, y1, x2, y2;
this->aRef.getPos(x1, y1);
double r = pow(x1 - x2, );
r += pow(y1 - y2, );
return sqrt(r);
}
bool Circle::isInter(const Circle & aRef)const
{
double min_dist = this->getRadius() + aRef.getRadius();
double dist = this->getDist(aRef);
if (min_dist >= dist)
{
return true;
}
return false;
}

18.动态数组类的实现

#ifndef ARRAY_H
#define ARRAY_H
#include <iostream>
class Array
{
public:
Array(const int aCount = );
Array(const Array &aArray);
~Array();
void setCount(const int aCount);
int getValue(const int aIndex)const;
void setValue(const int aIndex, const int aValue);
private:
int m_iCount, *m_pArray;
};
#endif
Array:Array(const int aCount) : m_iCount(aCount), m_pArray(NULL)
{
if (aCount <= )
{
return false;
}
m_pArray = new int[aCount];
}
Array:Array(const Array &aArray) : m_iCount(aArray.m_iCount), m_pArray(NULL)
{
if (aArray.m_iCount <= )
{
return false;
}
this->m_pArray = new int[aArray.m_iCount];
for (int I = ; i < m_iCount; i++)
{
m_pArray[i] = aArray.m_pArray[i];
}
}
Array::~aArray()
{
delete[]m_pArray;
}
void Array::setCount(const int aCount)
{
if (!aCount)
{
return false;
}
int min_count = (aCount < m_iCount) ? aCount : m_iCount;
m_iCount = aCount;
int *nArray = new int[aCount];
if (min_count)
{
memcpy(nArray, m_pArray, min_count*sizeof(int));
}
delete[]m_pArray;
m_pArray = nArray;
} int Array::getValue(const int aIndex)const
{
return m_pArray[aIndex];
}
void Array::setValue(const int aIndex, const int aValue)
{
if (!m_pArray)
{
return false;
}
if (aIndex >= m_iCount)
{
return false;
}
m_pArray[aIndex] = aValue;
}

19.复数类的实现

Complex::Complex(double aReal, double aImag)
{
m_dImag = aImag;
m_dReal = aReal;
}
Complex::~Complex(){}
double Complex::GetReal()const
{
return m_dReal;
}
double Complex::GetImag()const
{
return m_dImag;
}
Complex Complex::Add(Complex &aRef)const
{
Complex result;
result.m_dImag = m_dImag + aRef.m_dImag;
result.m_dReal = m_dReal + aRef.m_dReal;
return result;
} .字符串类的实现 #include <iostream>
using namespace std;
class String{
public:
String(const char* str = NULL);
String(const String &other);
~String()
{
delete[]m_data;
}
void display()const;
private:
char *m_data;
};
String::String(const char* str)
{
if (!str)
{
m_data = ;
}
else
{
m_data = new char[strlen(str) + ];
strcpy(m_data, str);
}
} String::String(const String & other)
{
if (this != &other)
{
m_data = new char[strlen(other.m_data) + ];
strcpy(m_data, other.m_data);
}
}
void String::display()const
{
cout << m_data << endl;
}

21.友元类 友元关系不能被继承 单向不具备交换性 不具有传递性

22.指针与const 划线法 const 与 指针关系 左变指向 右变数据 双双冻结

23.构造函数是特殊的成员函数,重点注意与类同名、无返回类型、有形参表(可为空)、函数体.

一个类可以有多个构造函数,但形参数目或类型不能均同.形参指定了初始化式.

24.显示定义一个构造函数:没有形参的默认构造函数.默认构造函数,无显示初始化式.

举个栗子
vector<int> vi; //无元素向量对象
string s; //空字符串
Sales_item item; //空的Sales_item对象

25.构造函数Public,不可以Private.否则不能初始化对象.

26.函数重载是为了用一个函数名实现不同函数功能.

27.函数重载和重复声明有区别.形参表和返回类型一致,就近采用,单一声明.同表不同型,第一正确.

1、进程与线程的区别

(1)粒度性分析:线程的粒度小于进程。

(2)调度性分析:进程是资源拥有的基本单位,线程是独立调度与独立运行的基本单位,出了寄存器,程序计数器等必要的资源外基本不拥有其他资源。

(3)系统开销分析:由于线程基本不拥有系统资源,所以在进行切换时,线程切换的开销远远小于进程。

2、进程的状态及其转换

3、进程同步与互斥的区别

互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。

简单地说:同步体现的是一种协作性,互斥体现的是一种排他性。

4、进程间的通信方式有哪些?

1管道( pipe )管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

2)有名管道 (named pipe) 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

3)信号量( semophore ) 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

4消息队列( message queue ) 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

5)信号 ( sinal ) 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

6)共享内存( shared memory ) 共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。

7)套接字( socket ) 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

5、作业(或进程)的调度算法有哪些?

1)先来先服务(FCFSFirst-Come-First-Served: 此算法的原则是按照作业到达后备作业队列(或进程进入就绪队列)的先后次序来选择作业(或进程)。

2)短作业优先(SJF,Shortest Process Next):这种调度算法主要用于作业调度,它从作业后备队列中挑选所需运行时间(估计值)最短的作业进入主存运行。

3)时间片轮转调度算法(RRRound-Robin):当某个进程执行的时间片用完时,调度程序便停止该进程的执行,并将它送就绪队列的末尾,等待分配下一时间片再执行。然后把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。这样就可以保证就绪队列中的所有进程,在一给定的时间内,均能获得一时间片处理机执行时间。

4)高响应比优先(HRRNHighest Response Ratio Next: 按照高响应比((已等待时间+要求运行时间)/ 要求运行时间)优先的原则,在每次选择作业投入运行时,先计算此时后备作业队列中每个作业的响应比RP然后选择其值最大的作业投入运行。

5 优先权(Priority)调度算法: 按照进程的优先权大小来调度,使高优先权进程得到优先处理的调度策略称为优先权调度算法。注意:优先数越多,优先权越小。

6)多级队列调度算法:多队列调度是根据作业的性质和类型的不同,将就绪队列再分为若干个子队列,所有的作业(或进程)按其性质排入相应的队列中,而不同的就绪队列采用不同的调度算法。

6、死锁产生的原因,死锁产生的必要条件是什么,如何预防死锁,如何避免死锁,死锁定理?

死锁产生的原因:(1)竞争资源;(2)进程推进顺序不当。

死锁产生的必要条件:

1)互斥条件:一个资源一次只能被一个进程所使用,即是排它性使用。

2)不剥夺条件:一个资源仅能被占有它的进程所释放,而不能被别的进程强占。

3)请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源要求,而该资源又已被其它进程占有,此时请求进程阻塞,但又对已经获得的其它资源保持不放。

4)环路等待条件:当每类资源只有一个时,在发生死锁时,必然存在一个进程-资源的环形链。

预防死锁:破坏四个必要条件之一。

死锁的避免:银行家算法,该方法允许进程动态地申请资源,系统在进行资源分配之前,先计算资源分配的安全性。若此次分配不会导致系统从安全状态向不安全状态转换,便可将资源分配给进程;否则不分配资源,进程必须阻塞等待。从而避免发生死锁。

死锁定理:S为死锁状态的充分条件是:尚且仅当S状态的资源分配图是不可完全简化的,该充分条件称为死锁定理。

死锁的解除:

1)方法1强制性地从系统中撤消一个或多个死锁的进程以断开循环等待链,并收回分配给终止进程的全部资源供剩下的进程使用。

2)方法2使用一个有效的挂起和解除机构来挂起一些死锁的进程,其实质是从被挂起的进程那里抢占资源以解除死锁。

7、分段式存储管理、分页式存储管理,两个的区别?

分段式存储管理:分页存储管理是将一个进程的地址(逻辑地址空间)空间划分成若干个大小相等的区域,称为页,相应地,将内存空间划分成与页相同大小(为了保证页内偏移一致)的若干个物理块,称为块或页框(页架)。在为进程分配内存时,将进程中的若干页分别装入多个不相邻接的块中。

分页式存储管理:在分段存储管理方式中,作业的地址空间被划分为若干个段,每个段是一组完整的逻辑信息,如有主程序段、子程序段、数据段及堆栈段等,每个段都有自己的名字,都是从零开始编址的一段连续的地址空间,各段长度是不等的。

 

两者的区别:

1、页是信息的物理单位,分页是为了实现非连续的分配,以便解决内存的碎片问题,或者说分页是为了由于系统管理的需要。

2、页的大小固定是由系统确定的,将逻辑地址划分为页号和页内地址是由机器硬件实现的。而段的长度是不固定的,决定与用户的程序长度,通常由编译程序进行编译时根据信息的性质来划分。

3、分页式存储管理的作业地址空间是一维的,分段式的存储管理的作业管理地址空间是二维的。

 

8、页面置换算法有哪些?

1)最佳置换算法(Optimal):即选择那些永不使用的,或者是在最长时间内不再被访问的页面置换出去。(它是一种理想化的算法,性能最好,但在实际上难于实现)。

2)先进先出置换算法FIFO该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。

3)最近最久未使用置换算法LRULeastRecently Used):该算法是选择最近最久未使用的页面予以淘汰,系统在每个页面设置一个访问字段,用以记录这个页面自上次被访问以来所经历的时间T,当要淘汰一个页面时,选择T最大的页面。

 

4Clock置换算法:也叫最近未用算法NRU(Not RecentlyUsed)。该算法为每个页面设置一位访问位,将内存中的所有页面都通过链接指针链成一个循环队列。当某页被访问时,其访问位置“1”。在选择一页淘汰时,就检查其访问位,如果是“0”,就选择该页换出;若为“1”,则重新置为“0”,暂不换出该页,在循环队列中检查下一个页面,直到访问位为“0”的页面为止。由于该算法只有一位访问位,只能用它表示该页是否已经使用过,而置换时是将未使用过的页面换出去,所以把该算法称为最近未用算法。

5)最少使用置换算法LFU该算法选择最近时期使用最少的页面作为淘汰页。

C++精华笔记的更多相关文章

  1. TCP/IP协议精华笔记

    1.简介 TCP/IP协议并非单指TCP协议.IP协议,它是一组包括TCP协议和IP协议,UDP(User Datagram Protocol)协议.ICMP(Internet Control Mes ...

  2. JSPServlet精华笔记

    一.     JSP (Java Server Pages) JSP是指: ▶    在HTML中嵌入Java脚本代码 ▶    由应用服务器中的JSP引擎来编译和执行嵌入的Java脚本代码 ▶    ...

  3. C++之STL总结精华笔记

                       一.一般介绍      STL(StandardTemplate Library),即标准模板库,是一个具有工业强度的,高效的C++程序库.它被容纳于C++标准程 ...

  4. MySQL精华笔记

    1.mysql分为 server 层和存储引擎: server 层: 1.连接器:管理连接权限验证 2.查询缓存:命中缓存直接换回查询结果 3.分析器:分析语法 4.优化器:生成执行计划,选择索引 5 ...

  5. iteye上总结的编程精华资源

    原文:http://www.iteye.com/magazines/130 博客是记录学习历程.分享经验的最佳平台,多年以来,各路技术大牛在ITeye网站上产生了大量优质的技术文章,并将系列文章集结成 ...

  6. DDD领域驱动设计理论篇 - 学习笔记

    一.Why DDD? 在加入X公司后,开始了ASP.NET Core+Docker+Linux的技术实践,也开始了微服务架构的实践.在微服务的学习中,有一本微软官方出品的<.NET微服务:容器化 ...

  7. 《代码整洁之道》(Clean Code)- 读书笔记

    一.关于Bob大叔的Clean Code <代码整洁之道>主要讲述了一系列行之有效的整洁代码操作实践.软件质量,不但依赖于架构及项目管理,而且与代码质量紧密相关.这一点,无论是敏捷开发流派 ...

  8. 《容器化.NET应用架构指南》脑图学习笔记(第一部分)

    一.关于这本官方“圣经” 作为.NET程序员,对于微软官方推动的架构示例总是特别关注,从PetShop到MusicStore再到eShopOnContainers,每一次关注,都会了解到业界最新的架构 ...

  9. 【劳动节江南白衣Calvin 】我的后端开发书架2015

    自从技术书的书架设定为”床底下“之后,又多了很多买书的空间.中国什么都贵,就是书便宜. 不定期更新,在碎片化的阅读下难免错评. 书架主要针对Java后端开发,书单更偏爱那些能用简短流畅的话,把少壮不努 ...

随机推荐

  1. 和为s的两个数字 【微软面试100题 第十四题】

    题目要求: 输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s.如果有多对数字的和等于s,输出任意一对即可. 例如输入数组{1,2,4,7,11,15}和数字15.由于4+1 ...

  2. webdriver高级应用- 操作富文本框

    富文本框的技术实现和普通的文本框的定位存在较大的区别,富文本框的常见技术用到了Frame标签,并且在Frame里面实现了一个完整的HTML网页结构,所以使用普通的定位模式将无法直接定位到富文本框对象. ...

  3. Selenium WebDriver- 通过源码中的关键字找到我们要操作的句柄,用于多个窗口之间切换

    #encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webdriver i ...

  4. MySQL5.7从入门到精通 (视频教学版) 刘增杰 编著

    第1章 初识MySQL MySQL是一个开放源代码的数据库管理系统(DBMS),它是由MySQL AB公司开发.发布和支持的.MySQL是一个跨平台(Windows.Linux.UNIX.MacOS) ...

  5. ubuntu系统14.04安装php5

    背景:        阅读新闻 Ubuntu 14.04 LTS 安装 LNMP Nginx\PHP5 (PHP-FPM)\MySQL [日期:2014-05-27] 来源:imcn.me  作者:L ...

  6. 【FFT】学习笔记

    首先,多项式有两种表示方式,系数表示和点值表示 对于两个多项式相乘而言,用系数表示进行计算是O(n^2)的 而用点值表示进行计算是O(n)的 那么我们自然就会去想如果把系数表示的多项式转化为点值表示的 ...

  7. http请求代理proxy-ajax

    今天把项目中的反向代理脚本程序抽成了一个插件,通过配置文件配置代理的http请求,这样使用起来比较方便,每位开发成员都可以用自己配置的代理调试代码.也可以用来直接做http代理,你甚至都不用Charl ...

  8. jquery中object对象循环遍历的方法

    一个朋友问对象如何转为数组,当我问他为啥要转得时候,他告诉我,数组可以用js循环遍历,而对象则不可以.其实呢,对象同样可以循环遍历的啊.不用转换也可以循环!说明你对js或者jquery的某些操作不是很 ...

  9. 马士兵hadoop第一课:虚拟机搭建和安装hadoop及启动(转)

    马士兵hadoop第一课:虚拟机搭建和安装hadoop及启动 马士兵hadoop第二课:hdfs集群集中管理和hadoop文件操作 马士兵hadoop第三课:java开发hdfs 马士兵hadoop第 ...

  10. Linux内核解析之标准I/O库

    当Linux创建一个进程时,会自动创建3个文件描述符0,1,2,分别对应标准输入,标准输出,错误输出.C库中与文件描述符对应的是文件指针.查看C库头文件stdio.h中的源码 typedef stru ...