指针

C++类内存分布

房东的猫 提交于 2020-03-30 02:39:27
转自:http://www.cnblogs.com/jerry19880126/p/3616999.html C++类内存分布 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承、虚函数存在的情况下。 工欲善其事,必先利其器,我们先用好Visual Studio工具,像下面这样一步一步来: 先选择左侧的C/C++->命令行,然后在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内存布局,如果写上/d1 reportSingleClassLayoutXXX(XXX为类名),则只会打出指定类XXX的内存布局。近期的VS版本都支持这样配置。 下面可以定义一个类,像下面这样: 1 class Base 2 { 3 int a; 4 int b; 5 public: 6 void CommonFunction(); 7 }; 然后编译一下,可以看到输出框里面有这样的排布: 这里不想花精力在内存对齐因素上,所以成员变量都设为int型。 从这里可以看到普通类的排布方式,成员变量依据声明的顺序进行排列(类内偏移为0开始),成员函数不占内存空间。 再看下继承,往后面添加如下代码: 1 class DerivedClass: public Base 2 { 3 int c; 4 public

C++四种强制转换

梦想的初衷 提交于 2020-03-30 02:37:35
C语言的强制转换为在数据面前之间加数据类型进行转换,即(目标数据类型)原数据类型。 c++ 为了更好的 区分强制转换的类型 ,达到 见其名知其意 的效果,共将强制转换分为四种,即 1、static_cast<目标数据类型>原数据类型 2、const_cast<目标数据类型>原数据类型 3、reinterpret_cast<目标数据类型>原数据类型 4、dynamic_cast<目标数据类型>原数据类型 解析 static_cast<>() 1)用于类层次结构中基类和派生类之间指针或引用的转换 进行上行转换(把派生类的指针或引用转换成基类表示)是安全的 进行下行转换(把基类的指针或引用转换为派生类表示),由于没有动态类型检查,所以是不安全的 2)用于基本数据类型之间的转换,如把int转换成char。这种转换的安全由开发人员来保证 3)把空指针转换成目标类型的空指针 4)把任何类型的表达式转换为void类型 注意:static_cast不能转换掉expression的const、volitale或者__unaligned属性。  static_cast:可以实现C++中内置基本数据类型之间的相互转换。 如果涉及到类的话,static_cast只能在 有相互联系的类型中进行相互转换, 不一定包含虚函数。 const_cast<>() cost_cast即用于强制转换 指针或者引用 的

Debug版本和Release版本的区别

这一生的挚爱 提交于 2020-03-29 19:17:15
一、Debug 和 Release 编译方式的本质区别 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 Debug 和 Release 的真正秘密,在于一组编译选项。下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起 Release 版错误,在此不讨论) Debug 版本: /MDd /MLd 或 /MTd 使用 Debug runtime library(调试版本的运行时刻函数库) /Od 关闭优化开关 /D "_DEBUG" 相当于 #define _DEBUG,打开编译调试代码开关(主要针对 assert函数) /ZI 创建 Edit and continue(编辑继续)数据库,这样在调试过 程中如果修改了源代码不需重新编译 /GZ 可以帮助捕获内存错误 /Gm 打开最小化重链接开关,减少链接时间 Release 版本: /MD /ML 或 /MT 使用发布版本的运行时刻函数库 /O1 或 /O2 优化开关,使程序最小或最快 /D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数) /GF 合并重复的字符串,并将字符串常量放到只读内存,防止 被修改

数据结构——树与二叉树

和自甴很熟 提交于 2020-03-29 19:01:14
目录 导言 什么是树 树结构定义 树的结点 结点分类 结点的联系 结点的层次 有序树 森林 相比线性结构 树的存储结构 双亲表示法 结构体定义 描述法举例 孩子表示法 描述法举例 结构体定义 孩子兄弟表示法 描述法举例 二叉树 二叉树的定义 特殊的二叉树 斜树 满二叉树 完全二叉树 二叉树的性质 二叉树的存储结构 顺序存储 链式存储 结构体定义 二叉树的基本操作 二叉树的遍历 从斐波那契数列说起 遍历算法 建立二叉树 拓展二叉树 建树算法 复制二叉树 获取二叉树的深度 统计二叉树的结点数 线索二叉树 描述前驱与后继 线索二叉树结点结构体定义 线索化 遍历线索二叉树 参考资料 导言 轩辕剑是一个经典的中文角色扮演游戏,通过对历史内容的考究,与精彩感人的剧情结合,使得这个系列被公认为华人世界的两大经典角色扮演游戏系列之一。我最为喜欢的两部是《轩辕剑叁:云和山的彼端》和《轩辕剑叁外传:天之痕》,剧情感人精彩、别有深意,2D的场景细致美观、独具特色……当然,我这次仍然不是来给你推荐游戏的,而是想对其中一个场景做点文章。 “建木”是上古先民崇拜的一种圣树,传说建木是沟通天地人神的桥梁,在《轩辕剑叁外传:天之痕》中的仙山岛,利用水墨画的风格进行了描绘,是我最喜欢的游戏场景之一。其中就有对“海中建木”的描绘。“海中建木”无疑是一颗巨大的树,这棵树也肯定是由无数的根、枝、叶组成的,如果我们把

面试题二十三:如果一个链表中包含环链,如何找到环的入口

早过忘川 提交于 2020-03-29 15:10:56
方法一:步骤1.确定环存在:指针A一次走一步,指针B一次走两步,如果相遇则出现环。 步骤2。确定环的数量:A继续走,b不动,计数k,再次相遇则可得计数结果 步骤3. 寻找入口:指针A从头结点先走k步,然后一起向前,相遇时的节点就是入口 来源: https://www.cnblogs.com/niliuxiaocheng/p/12592253.html

一些面试题,转关注的一个博客

一个人想着一个人 提交于 2020-03-29 12:13:37
腾讯面试题: tcp 三次握手的过程, accept 发生在三次握手哪个阶段? 答accept发生在三次握手之后。 第一次握手:客户端发送syn包(syn=j)到服务器。 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个ASK包(ask=k)。 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)。 三次握手完成后,客户端和服务器就建立了tcp连接。这时可以调用accept函数获得此连接。 const 的含义及实现机制,比如: const int i, 是怎么做到 i 只可读的? const用来说明所定义的变量是只读的。 这些在编译期间完成,编译器可能使用常数直接替换掉对此变量的引用。 用 UDP 协议通讯时怎样得知目标机是否获得了数据包 可以在每个数据包中插入一个唯一的ID,比如timestamp或者递增的int。 发送方在发送数据时将此ID和发送时间记录在本地。 接收方在收到数据后将ID再发给发送方作为回应。 发送方如果收到回应,则知道接收方已经收到相应的数据包;如果在指定时间内没有收到回应,则数据包可能丢失,需要重复上面的过程重新发送一次,直到确定对方收到。 求一个论坛的在线人数,假设有一个论坛,其注册 ID 有两亿个,每个 ID 从登陆到退出会向一个日志文件中记下登陆时间和退出时间

5数组指针和引用:数组

谁说我不能喝 提交于 2020-03-29 10:06:19
数组 一维数组:数据类型 数组名 [常量表达式] 注意: 命名规则和变量名相同 数组后面一定是[],方括号内 是常量表达式 常量表达式表达元素的个数,即数组的长度 定义数组的常量表达式不能是变量 引用: 一维数组引用的一般形式:数组名[下标] 数组元素的下标起始值为0 初始化: 单个元素逐一赋值 a[10]=1;a[9]=100;...... 聚合方式赋值 int a[10]={1,2,.....10} ; int a[]={1,2,.....10} ; int a[10]={1,2,.....7} 没被赋值的元素 默认补0 二维数组:数据类型 数组名[常量表达式1][常量表达式2] 注意: 数组名按照标识符命名 二维数组有两个下标 a[3][4] 下标一定是整数a[3][4]表示有12个元素 声明的时候 下标不能是变量 一维数组:连续的内存单位进行排序 二维数组:存储形式与一维相同 引用: 数组名[下标][下标] 起始值从0开始 初始化: 单一元素逐一赋值 聚合方式赋值 int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int a[3][4]={1,2,3,4} 后面补0; int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}} 字符数组:char 数组名 [常量表达式] 初始化: 聚合方式 char a

C++之指向函数的指针

淺唱寂寞╮ 提交于 2020-03-29 09:57:34
1 #include <iostream> 2 #include <string> 3 //#include "Sales_item.h" 4 #include "Sales_item.cpp" 5 6 using namespace std; 7 //使用typedef简化定义 8 typedef bool (*pf)(const string &s1,const string &s2); 9 typedef int (*PF)(int *, int); 10 11 12 bool length(const string &s1,const string &s2) 13 { 14 return s1.size()==s2.size(); 15 } 16 17 void useBigger(const string &s1,const string &s2,bool (*pf)(const string &s1,const string &s2)) 18 { 19 cout<<length(s1,s2)<<endl; 20 } 21 //ff是一个函数名 有一个形参 x 返回的结果为一个函数指针int(*)(int *,int) 22 //int (*ff(int x))(int *, int) 23 //{ 24 // 25 //} 26 //等同于上边的定义 27 //PF(

使用指针传递二维数组参数

早过忘川 提交于 2020-03-29 09:11:11
  在c语言中,有的时候会需要传递一个二维数组给函数。然而直接传递二维数组并不像传递一维数组那样容易,我们最好是借用指针来传递二维数组。   要用指针传递二维数组,则必须对二维数组的储存方式有个了解。二维数组在内存中其实也是按照一个序列来排列的,毕竟内存只有高低之分,只有一个方向。因此,二维数组的储存实现是一行行来存储的,存完一行再存下一行,并且是紧挨着存储。   比如定义int a[3][4],那么每行有4个数,一共3行。用指针p来表示数组,int *p;*p = &a[0][0],那么要用p表示a[2][1],就是*(p+2*4+1),这样就能通过传递指针p和表示二维数组长度的数来传递二维数组。 1 /*测试用指针传递二维数组*/ 2 /*by telnetning 13.3.20*/ 3 4 #include <stdio.h> 5 6 /*函数求二维数组所有的数的和的大小*/ 7 int Sum(int *p,int i,int j){ 8 int m; 9 int n; 10 int s; 11 for(n=0;n<=i;n++){ 12 for(m=0;m<=j;m++){ 13 s=*(p+(n*3)+m); 14 } 15 } 16 return s; 17 } 18 int main(){ 19 int s; 20 int a[3][3]; 21 int i,j;

C语言中字符数组库函数

拈花ヽ惹草 提交于 2020-03-29 04:04:25
以下内容摘自《C程序设计教程》(美)H.M.Deitel P.J.Deitel著,薛万鹏等译,机械工业出版社。 void *memccpy (void *dest, const void *src, int c, size_t n); 从sr*所指向的对象复制*个字符到*est所指向的对象中。如果复制过程中遇到了字符c则停止复制,返回指针指向dest中字符c的下一个位置;否则返回NULL。 void *memcpy (void *dest, const void *src, size_t n); 从sr*所指向的对象复制*个字符到*est所指向的对象中。返回指针为dest的值。 void *memchr (const void *s, int c, size_t n); 在s所指向的对象的前n个字符中搜索字符c。如果搜索到,返回指针指向字符c第一次出现的位置;否则返回NULL。 int memcmp (const void *s1, const void *s2, size_t n); 比较s1所指向的对象和s2所指向的对象的前n个字符。返回值是s1与s2第一个不同的字符差值。 int memicmp (const void *s1, const void *s2, size_t n); 比较s1所指向的对象和s2所指向的对象的前n个字符,忽略大小写