刷题日记-自己的以及网友的总结

这篇博客记录我从2017年4月24号开始,每天刷题的日记,以后每天会更新!
地方

/第一天

在此声明,有些文字太多,直接拷贝网友的回答,在此谢谢各位网友!
如有侵权,请提示删除。

1.堆和内存问题

为了最大利用内存空间,堆和栈设计为从两端相向生长,堆是程序员分配的,按照人们的习惯低地址分配低内存高地址分配高内存,故堆从低地址开始向上增长,相应的栈从高地址向下增长。

2.一个程序执行的过程

编辑:
指编写程序代码。
预处理:
根据预处理指令重新组装C/C++源代码,处理后的文件,没有宏定义、特殊符号,条件编译指令,文件的含义同原本文件一样,只是内容略有不同。
编译:
将代码编译为机器可读的汇编语言
链接:
将所有目标文件和相应的库文件链接起来,总成一个整体(如:分别定义在两个文件中的变量,函数等)

3.关于中间件

中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件。相连接的系统,即使它们具有不同的接口,但通过中间件相互之间仍能交换信息。执行中间件的一个关键途径是信息传递。通过中间件,应用程序可以工作于多平台或OS环境。
(简单来说,中间件并不能提高内核的效率,一般只是负责网络信息的分发处理)

4.关于成员列表初始化的问题

在构造函数中需要初始化列表初始化的有如下三种情况 1.带有const修饰的类成员 ,如const int a ;
2.引用成员数据,如 int& p;
3.带有引用的类变量,如: class A {
private:
int &a;
};
class B{
private:
A c;
}
这里的c需要用初始化列表进行初始化。

5.内存对齐问题

在默认情况下,为了方便对结构体内元素的访问和管理,当结构体内的元素长度都小于处理器的位数时,就以最长的元素为对齐单位,也就是说,结构体的长度一定是最长元素的整数倍。如果有元素长度超过处理器位数,则以处理位数为对齐单位,结构体的长度为处理器位数的整数倍。
但是结构体内类型相同的连续元素和数组一样,将在连续的空间内。

6.||和&& 问题

||类似于短路问题:
如果左边为真,则直接连通,返回true
&&类似于断路问题
只有左边为真的情况下,才进行右边判断,当两者都为真时,才返回true.

7.dynamic_cast<>

dynamic_cast<>用于C++类继承多态间的转换,分为:
1.子类向基类的向上转型(Up Cast)
2.基类向子类的向下转型(Down Cast)
其中向上转型不需要借助任何特殊的方法,只需用将子类的指针或引用赋给基类的指针或引用即可,dynamic_cast向上转型其总是肯定成功的。

而向下转换时要特别注意:dynamic_cast操作符,将基类类型的指针或引用安全的转换为派生类的指针或引用。dynamic_cast将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理。这也是dynamic_cast与其他转换不同的地方,dynamic_cast涉及运行时类别检查,如果绑定到引用或指针的对象不是目标类型的对象,则dynamic_cast失败。如果是指针类型失败,则dynamic_cast的返回结果为0,如果是引用类型的失败,则抛出一个bad_cast错误。
注意:dynamic_cast在将父类cast到子类时,父类必须要有虚函数。因为dynamic_cast运行时需要检查RTTI信息。只有带虚函数的类运行时才会检查RTTI。

8.串 –next数组

next数组下标从1开始计算
next[1] 肯定是 0
next[2] 肯定是 1
next[n]
的情况,将前面n-1个字符,计算从首尾开始组成最大的相同子串的长度,如果找到,那么next值是该长度加1,否则next值是1。
举例
next[6]的计算,字符串第六位是 a,(ababa*a*ababaa)
将前面的5个字符,从头尾开始取4个组成子串比较,如果不相等,则从首尾取3个字符组成子串继续比较,并以此类推,
如果一直比较到最后一个字符都不相等,那么该next值为1。
4个字符的情况:abab : baba
3个字符的情况:aba : aba 此时相等,那么next[6] = 3+1 = 4

/好了,今天就到这了,发现,晚上不适合长时间刷题,有点累,明天继续/

///日了狗,写的没保存,白写了,重新开始更新//第二天//

1.nextval数组

求nextval数组值的第二种方法
模式串
a b a a b c a c
next值
0 1 1 2 2 3 1 2
nextval值
0 1 0 2 1 3 0 2
1.第一位的nextval值必定为0,第二位如果于第一位相同则为0,如果不同则为1。

2.第三位的next值为1,那么将第三位和第一位进行比较,均为a,相同,则,第三位的nextval值为0。

3.第四位的next值为2,那么将第四位和第二位进行比较,不同,则第四位的nextval值为其next值,为2。

4.第五位的next值为2,那么将第五位和第二位进行比较,相同,第二位的next值为1,则继续将第二位与第一位进行比较,不同,则第五位的nextval值为第二位的next值,为1。

5.第六位的next值为3,那么将第六位和第三位进行比较,不同,则第六位的nextval值为其next值,为3。

6.第七位的next值为1,那么将第七位和第一位进行比较,相同,则第七位的nextval值为0。

7.第八位的next值为2,那么将第八位和第二位进行比较,不同,则第八位的nextval值为其next值,为2。

2.前缀、中缀、后缀表达式
前缀表达式:
称为波兰表达式
计算:
从右向左扫描,遇到数字,就入栈,遇到操作符,则输出相应的数字,计算然后入栈,继续扫描。
中缀表达式转前缀表达式:
从右向左扫描,遇到操作数则输出,遇到操作符,若该操作符优先级大于等于栈顶操作符的优先级,则入栈,否则先将比它优先的操作符出栈,然后入栈。

后缀表达式:

计算:
从前向后扫描,遇到操作数则入栈,遇到操作符,则出栈相应数字,计算后压入栈,继续扫描,直到栈为空。

中缀表达式转后缀表达式:
从前往后扫描,若遇到操作数则输出,遇到操作符,如该操作符优先级大于栈顶优先级,则入栈,否则出栈优先级比它大或等于的操作符,然后入栈。直到栈空。

//今天是第三天,加油兄弟/

这次主要是针对网易春招的12道题的总结

1. 双核处理

一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间。
题目分析:
从题目来看,是要分配一下CPU处理任务的顺序,使得处理时间最小。两个核可以同时处理,想要总的时间最少,则需要分摊到每个核的任务达到最大,两个核在同一时间处理,所需的总时间就少了。那么问题就归结为,怎么安排任务,让单核处理时间最长,,很熟悉吧,对,这就跑到我们最熟悉的0-1背包上来了,这样问题就很容易解决了。
总处理时间的一半,sum/2为单核的最大容许处理时间,接下来就看怎么放了。这就牵扯到了简单的动态规划,需要生成dp数组,dp[][],我们可以令dp[i][j]为放第i个任务时,最大容量为j时的最大价值(即此时的处理时间),那么
dp[i][j]=max{dp[i-1][j],dp[i-1][j-Wi]+Vi}
就是说当前最大处理时间,为不放第i个任务的处理时间 与 放第i个任务的处理时间 之间的最大值。我们将dp数组填满,那么dp[n][sum/2]就是所求 的最小时间(因为一起工作,单核完成了,另一个核也就同时完成了,所以总时间其实就是单核处理的时间)
不得不说 动态规划 很牛逼!

2. 赶去公司

终于到周末啦!小易走在市区的街道上准备找朋友聚会,突然服务器发来警报,小易需要立即回公司修复这个紧急bug。假设市区是一个无限大的区域,每条街道假设坐标是(X,Y),小易当前在(0,0)街道,办公室在(gx,gy)街道上。小易周围有多个出租车打车点,小易赶去办公室有两种选择,一种就是走路去公司,另外一种就是走到一个出租车打车点,然后从打车点的位置坐出租车去公司。每次移动到相邻的街道(横向或者纵向)走路将会花费walkTime时间,打车将花费taxiTime时间。小易需要尽快赶到公司去,现在小易想知道他最快需要花费多少时间去公司。

题目分析:
简单总结一下就是,从原点—出租车—-公司,其中出租车有很多,位置也不一样,应该选哪个出租车点赶去公司花的时间最小。我们可以算出每条路线所花费的时间,然后再找出最小值,那么这就是花费的最小时间,时间复杂度为O(N)。

3. 调整队形

在幼儿园有n个小朋友排列为一个队伍,从左到右一个挨着一个编号为(0~n-1)。其中有一些是男生,有一些是女生,男生用’B’表示,女生用’G’表示。小朋友们都很顽皮,当一个男生挨着的是女生的时候就会发生矛盾。作为幼儿园的老师,你需要让男生挨着女生或者女生挨着男生的情况最少。你只能在原队形上进行调整,每次调整只能让相邻的两个小朋友交换位置,现在需要尽快完成队伍调整,你需要计算出最少需要调整多少次可以让上述情况最少。例如:
GGBBG -> GGBGB -> GGGBB
这样就使之前的两处男女相邻变为一处相邻,需要调整队形2次 。

题目分析:
看起来就是男女排队,最终男女分别占一边。有两种情况:1.女生占左边;2.女生占右边。 我们知道这两种情况调整次数有可能不同,所以分别计算出在两边的调整次数,然后取最小值,就是最小次数。

4.消除重复元素

小易有一个长度为n序列,小易想移除掉里面的重复元素,但是小易想是对于每种元素保留最后出现的那个。小易遇到了困难,希望你来帮助他。

题目分析:
我的思路时间复杂度大概是O(N^2),循环n次,每一次,搜索一个位置,如果此位置不为maxsize,则从此位置开始进行内循环,搜索相同的字母,若有相同的则把自己置maxsize。直至外层结束。

5.魔力手环

小易拥有一个拥有魔力的手环上面有n个数字(构成一个环),当这个魔力手环每次使用魔力的时候就会发生一种奇特的变化:每个数字会变成自己跟后面一个数字的和(最后一个数字的后面一个数字是第一个),一旦某个位置的数字大于等于100就马上对100取模(比如某个位置变为103,就会自动变为3).现在给出这个魔力手环的构成,请你计算出使用k次魔力之后魔力手环的状态。

题目分析:
就像一个轮盘,每转动一次,就按规则更新数字。但我这样做,时间复杂度就为O(N*K),k为转动次数。有点超时了。所以看了下网友的答案,我只能说很精妙。
由于每次规则都一样,是当前+后面=当前;所以考虑用矩阵的快速幂。
例:vector=[1 2 5 4 7 8] 转动一次,相当于乘以一个矩阵
1 0 0 0 0 1
1 1 0 0 0 0
0 1 1 0 0 0
0 0 1 1 0 0
0 0 0 1 1 0
0 0 0 0 0 1
那么转K次,就相当于乘以这矩阵k次。
因此,需要先写一个矩阵相乘的函数,然后再写一个求矩阵快速幂的函数,剩下的就好办了。我自己试了试,求快速幂,不用递归求得结果是错的,但是递归还没看懂!,以后再看看吧。

6.工作安排

现在有n位工程师和6项工作(编号为0至5),现在给出每个人能够胜任的工作序号表(用一个字符串表示,比如:045,表示某位工程师能够胜任0号,4号,5号工作)。现在需要进行工作安排,每位工程师只能被安排到自己能够胜任的工作当中去,两位工程师不能安排到同一项工作当中去。如果两种工作安排中有一个人被安排在的工作序号不一样就被视为不同的工作安排,现在需要计算出有多少种不同工作安排计划。

题目分析:
看起来,就是将工人分配到相应的工作中去,且一个工作只能有一个工人,有几种不同的分法(限制条件是工人有些工作不适合)。那么这就有点像图的遍历时用到的深度优先搜索的情况了,首先从第一个工人开始,先列出他能胜任的工作,从第一个工作开始,判断如果该工作可以做,然后标记,紧接着看看下一个人能不能做,同样的方法,看他能干的工作—–。一遍搜索完了,就count++,然后把数组初始化,为下一种情况做准备。

7. 集合

小易最近在数学课上学习到了集合的概念,集合有三个特征:1.确定性 2.互异性 3.无序性.
小易的老师给了小易这样一个集合:
S = { p/q | w ≤ p ≤ x, y ≤ q ≤ z }
需要根据给定的w,x,y,z,求出集合中一共有多少个元素。小易才学习了集合还解决不了这个复杂的问题,需要你来帮助他。

题目分析:
看起来又是求有多少种情况的问题,但是可以看出这是一个集合问题,可以想到c++中的set函数,它里面的元素都是不同的,所以将p/q(好像还要 *1.0000000,提高精度)放入set,看看set的大小,即为集合中的元素个数。

8.奇怪的表达式求值

常规的表达式求值,我们都会根据计算的优先级来计算。比如/的优先级就高于+-。但是小易所生活的世界的表达式规则很简单,从左往右依次计算即可,而且小易所在的世界没有除法,意味着表达式中没有/,只有(+, - 和 )。现在给出一个表达式,需要你帮忙计算出小易所在的世界这个表达式的值为多少 ?

题目分析:
就是用栈去求表达式,只不过规则与我们的不太一样而已
将其转换为后缀表达式(不考虑操作符的优先级),然后对后缀表达式求值,即可。

9.涂棋盘

小易有一块n*n的棋盘,棋盘的每一个格子都为黑色或者白色,小易现在要用他喜欢的红色去涂画棋盘。小易会找出棋盘中某一列中拥有相同颜色的最大的区域去涂画,帮助小易算算他会涂画多少个棋格。

题目分析:
可以看出,他是对每一列字符串,求最大相同子串长度,然后统计每一列最大相同子串长度,就得到最终结果。
所以只要解决了求一个字符串的最大相同子串的问题,那么其他的就简单了,只要将输入数据放入一个矩阵,就好操作了。

10.小易记单词

小易参与了一个记单词的小游戏。游戏开始系统提供了m个不同的单词,小易记忆一段时间之后需要在纸上写出他记住的单词。小易一共写出了n个他能记住的单词,如果小易写出的单词是在系统提供的,将获得这个单词长度的平方的分数。注意小易写出的单词可能重复,但是对于每个正确的单词只能计分一次。

题目分析:
我的想法是,先建立一个数据结构,存储字符串,且提供字符串长度,然后对小易写的每个单词,与系统提供的单词进行匹配,如果两个字符串长度相同,则进入匹配,匹配成功后,就将系统此单词置空。这样最差时间复杂度为O(N*M)
而网友的做法是,利用map

11.堆砖块

小易有n块砖块,每一块砖块有一个高度。小易希望利用这些砖块堆砌两座相同高度的塔。为了让问题简单,砖块堆砌就是简单的高度相加,某一块砖只能使用在一座塔中一次。小易现在让能够堆砌出来的两座塔的高度尽量高,小易能否完成呢。

题目分析:
这个直接看网友的方法了,有点像0-1背包,但是不能保证两个塔的高度一样,所以不能像双核处理那样计算,但是相同的是还是用到了dp数组,dp[i][j]为放第i块砖时,高度差为j时的低塔高度,这样高塔也就知道了,然后分为四种情况:1.放弃第i快砖头;2.放第i块砖,低塔还是低塔;3.放第i快砖头,低塔变高塔;4.直接放到高塔。
初始化dp[0][0]=0;dp[0][j]=负无穷。然后将dp数组填满,则dp[n][0]就是所求结果

12.分饼干

易老师购买了一盒饼干,盒子中一共有k块饼干,但是数字k有些数位变得模糊了,看不清楚数字具体是多少了。易老师需要你帮忙把这k块饼干平分给n个小朋友,易老师保证这盒饼干能平分给n个小朋友。现在你需要计算出k有多少种可能的数值

题目分析:
下面是直接抄网友的:
http://blog.csdn.net/wwe4023/article/details/70171648

///今天是第四天,加油!///

1.printf,栈,32bit little endian

little endian 小端格式 : 低位字节放在起始位置
big endian 大端格式 : 高位字节放在起始位置

c/c++函数参数从右向左入栈,且栈的生长方向为:从高向低。

printf中 %d 输出的是4bit 大小

2.关于inline关键字

用户定义inline关键字,只是代表了用户的请求,实际还要看编译器,如果编译器觉得该函数太大,则自动忽略此inline

头文件中,不仅要包含inline函数的声明,还要包含定义,且在定义体的前面必须加上Inline关键字

inline可以定义在源文件中,但多个源文件中的同名Inline函数,实现必须相同

类的成员函数,默认都是Inline (定义在类声明中的成员函数,自动变为Inline)

3.define

define 在预编译阶段,就将相应替换,而且作用到define定义的地方一直到整个文件结束,并且只看define的位置,不考虑它的逻辑位置

4.关于字符串常量

char* s1 = “Hello world”;
非法。char * s1 在栈中,而hello world 在字符串常量区

另外,s1[2]=’E’,也是非法的,因为常量是不可更改的

5.类 继承 作用域相关问题

在继承的时候,允许子类存在与父类同名的成员变量,但是并不覆盖父类的成员变量,他们同时存在。 因为给孩子类中没有定义print函数,所以会按照就近原则去寻找父类中是否有print函数。恰好父类中有这个函数,于是调用父类的print函数b.print(),而这个函数会调用父类的a变量。

6.非虚成员函数,静态绑定 NULL

根据<<深度探索c++对象模型>>里面说到的,普通成员函数在编译器实现时,大致经历一下转化过程:
1.改写函数的签名以安插一个额外的参数 - this指针
2. 将每一个对非静态成员数据成员的存取操作改为经由this指针来存取。
3.将成员函数重写成外部函数,函数名称经过“mangling”处理,使其在程序中有唯一的名字。
(重写成外部函数,是希望在实现成员函数的时候,使其效率接近普通非成员函数,尽可能避免带来额外开销)

pA->test();
对于这段代码,(编译阶段)编译器会先查看pA的类型,发现pA是一个类,并且有一个成员函数, 然后找到所有使用该成员函数的地方,将其重命名,并添加this参数如:
reName(A::this)(大概这样)

关键在于,虽然传了NULL指针,但是该函数没有用到this,所以还是会正常输出。

7. 逗号运算符

int a = 1, b = 2, c = 3, d = 4, e = 5;
printf(” %d\n”, func((a + b, b + c, c + a), (d, e)));
(d,e) 逗号运算符 ,返回值为e
即 逗号运算符返回值为表达式最后的值

8.enum

enum中:首元素不赋值的话,默认为0;后一个元素不赋值的话比前一个元素大1

/今天是第五天//

1.c语言未定义行为

c语言未定义行为,就是c标准没有定义的行为,c标准从没要求编译器判断这些未定义行为,所以在不同的编译器上编译,结果未知。
常见未定义行为:
1.同一运算符中多个操作数计算顺序未知, 如 + 左右两边操作数,此时会产生不定行为。
2.printf(“%d,%d\n”,++n,power(2,n));
这一函数,结果与先调用哪个函数参数有关。
3.对常量const进行修改
4.数组下标获取越界

2.fork()创建进程

http://blog.csdn.net/jason314/article/details/5640969

3.static const

在一个类中,const成员变量只能用初始化成员列表进行初始化
static变量,在类外进行初始化。
static int为静态变量,它的值始终保存在内存里,也就是上一次改变后的值

如果成员变量是引用,也需要初始化列表进行初始化

///今天是第六天///

1.关于字符数组初始化问题

http://blog.sina.com.cn/s/blog_a2e509c101014wjw.html

2.构造函数的执行顺序问题

当派生类中没有成员对象时:
先执行基类构造函数,最后派生类构造函数,释放顺序相反

当派生类中含有成员对象时:
先执行基类构造函数,其次执行成员对象构造函数,最后执行派生类构造函数,释放顺序相反。

3.sizeof

#pragma pack(2) 这行语句表示强制执行 按2字节对齐
union 是公用体,即只在特定时间用特定的变量,各个变量共享一段内存,所以这段内存,union {char c[13]; int i;} u sizeof(u)=16 , 默认按4字节对齐,其中最大的变量是13 所以最终为16=4*4

enum 枚举类型:
C++中枚举变量的大小是 1<=sizeof(enum)<=sizeof(int) 字节 (1-4字节)
枚举默认是用int类型来存储的,占4个字节。可以存储的最大值是0xffffff。
可以通过继承方式改变枚举的大小,例如:
enum TypeChar : unsigned char
{};
TypeChar 类型变量大小占用1字节

今天是第七天///

1.基类指针指向派生类对象

基类的指针指向派生类的对象
基类指针调用其虚成员函数,则会调用其真正指向对象的成员函数,而不是基类中定义的成员函数,若不是虚函数,则不管基类指针指向的是哪个派生对象,调用的都是基类中定义的那个函数

2.成员列表初始化

成员列表初始化的顺序只和成员变量声明的顺序有关。

3.delete 和 delete []

对于数组:
若为基本类型,则两者一样
若为自定义类型,则需要delete[] 因为它会针对对象数组对每一个对象调用析构函数

4.do while
do
{

} while() ;
后面必须加分号。

4.vector

vector的一个缺点就是它的内存分配是按照2的倍数分配内存的

5.sort 不稳定

std::sort 不是稳定的排序算法,它不保证“相等”元素的相对位置,使用 std::stable_sort 来保证这一点
6.STL容器
序列容器, 有vector, list, deque, string
关联容器, 有set, multiset, map, mulmap, hash_set, hash_map, hash_multiset, hash_multimap
其他的杂项: stack, queue, valarray, bitset

6.让类只能用new来创建

多个方法发反反复复编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,其实不光是析构函数,只要是非静态的函数,编译器都会进行检查。如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存。 因此, 将析构函数设为私有,类对象就无法建立在栈(静态)上了,只能在堆上(动态new)分配类对象 。

/之前CSDN手机绑定出了问题,就懒得弄,导致现在才弄好,就继续来吧,这次算是第七天/

1. set 和 multiset

set set

2.string

关于string的知识,下面这篇文章讲的很好
http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html
1.整数转string
sstream类型定义了一个有string形参的构造函数,
即: stringstream stream(s); 创建了存储s副本的stringstream对象,s为string类型对象
2.定义了名为str的成员,用来读取或设置stringstream对象所操纵的string值:
stream.str(); 返回stream中存储的string类型对象
stream.str(s); 将string类型的s复制给stream,返回void

于是……

string Int_to_String(int n)
{
ostringstream stream;
stream<<n;  //n为int类型
return stream.str();
}

2.拼接

str1+=str2
str1.append(str2)
第三种方法是 stringstream 头文件也是sstream

stringstream ss   
ss<<str

还有一个sprintf ,不过是针对char类型的
sprintf(cp,”%s”,t1 )

3.比较
bool operator==(const string &s1,const string &s2)const;//比较两个字符串是否相等
运算符”>”,”<”,”>=”,”<=”,”!=”均被重载用于字符串的比较;
int compare(const string &s) const;//比较当前字符串和s的大小
int compare(int pos, int n,const string &s)const;//比较当前字符串从pos开始的n个字符组成的字符串与s的大小
int compare(int pos, int n,const string &s,int pos2,int n2)const;//比较当前字符串从pos开始的n个字符组成的字符串与s中pos2开始的n2个字符组成的字符串的大小
int compare(const char *s) const;
int compare(int pos, int n,const char *s) const;
int compare(int pos, int n,const char *s, int pos2) const;
compare函数在>时返回1,<时返回-1,==时返回0

4.子串
string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串

3.sort.qsort的介绍
关于qsort的使用,这篇文章讲的很好
http://www.cnblogs.com/CCBB/archive/2010/01/15/1648827.html

void qsort(void base, int nelem, unsigned int width, int ( pfCompare)( const void , const void ));

关于sort
默认升序
包含头文件 #include
sort有两种用法
一种是sort(begin,end) 表示一个范围
另一种是sort(begin,end,compare)

3.小端存储

这是从牛客网 一位网友回答的图片

高位存储在高位地址
且地址从小到大

4.套接字
采用多路复用I/O监听3个套接字的数据时,如果套接字描述符分别是:5,17,19,则
1
select(int maxfd,struct fd_set* rdset,NULL,NULL)
其中maxfd为所有套接字描述符中最大的加一

5.数组越界

其实数组越界了编译还是能通过的,因为编译器不检查越界问题

6.实型常量

实型常量又称实数或浮点数。在C语言中可以用两种形式表示一个实型常量。

/今天是第八天///

1.字节对齐

 **联合体union**
union
{
char flag[3];
short value;
} sampleUnion;

对Union结构体,sizeof的取值不仅考虑sizeof最大的成员,还要考虑对齐字节,对齐字节的取值是取成员类型字节最大值与指定对齐字节(32位机器默认是4,64位机器默认是8)两者中的较小值,本题中成员类型最大值为short,2,与指定对齐字节4比较取2,所以要2字节对齐,如果去掉short变量,则取char的1字节对齐,结果为3

结构体


typedef struct
{
char flag[3];
short value;
} sampleStruct;

字符类型占1字节, 可以从任何地址开始
short类型占2字节, 必须从2字节倍数地址开始
int类型占4字节,必须从4字节倍数地址开始

2.memcpy memmove

memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。
但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。
函数原型:
char strcpy(char dest, const char *src) 把从src地址开始且含有NULL结束符的字符串复制到以dest开始的 地址空间
void *memcpy(void *dest, const void *src, size_t n); 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
void memmove( void dest, const void* src, size_t count ); 由src所指内存区域复制count个字节到dest所指内存区域。
void *memset(void *s, int ch, size_t n); 将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s

3.静态变量

静态变量放在程序的全局数据区,而不是在堆栈中分配,所以不可能导致堆栈溢出

若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度

若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度

设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题

//第九天///

1.数组地址和数组首元素地址

1.*(a + i) == a[i];
2.主要要理解“数组的地址”和“数组首元素的地址”是两个不同的概念
&a+1
&a是指数组地址,1是指偏移1个数组大小

第十天

1.CPU cache

主要是考察了CPU cache的预取操作,数组x[1000][1000]在内存中,是按行进行存储。D选项外部循环是按行进行,因此操作第i行时,会将第i行后面的部分数预取到cache中,操作速度最快。
ABC选项其中都有跳列的操作,不能发挥cache的预取操作功能。

///第十一天

1.不能被继承的类

1.将构造函数和析构函数设为私有

class sealedClass
{
public:
    void fun()
    {
        cout << "I'm fun" << endl;
    }
    static sealedClass * GetInstance()
    {
        return new  sealedClass;
    }
    static void deleteInstance(sealedClass * instance)
    {
        delete instance;
    }
private:
    sealedClass() { cout << "hello" << endl; };
    ~sealedClass(){ cout << "bye,bye" << endl; };
};

2.利用虚拟继承,将模板参数类型作为友元
此方法,对于有些编译器不支持,
不支持 模板参数类型作为类的友元。

template <typename T>class sealedClass
{
    friend T;
public:
    void fun()
    {
        cout << "I'm fun" << endl;
    }

private:
    sealedClass() { cout << "hello" << endl; };
    ~sealedClass(){ cout << "bye,bye" << endl; };
};

2

执行”int x=1;int y=~x;”语句后,y的值为?
运算对象是数字的补码而非原始二进制,用16进制表示的话,1的真值是0000 0001
它的补码也是0000 0001,那么它的取反之后为ffff fffe,这个也就是y的补码
那么现在就求y的真值,再取反加1,为8000 0002,所以为-2

///第十二天

1.extern

1.在一个源文件中定义,在其他需要使用的源文件中用extern声明。(仅一处定义,多处extern)
2.在一个源文件中定义,在其对应的头文件中extern声明,在其他需要使用该共享变量的源文件中包含该头文件即可
extern也可用来进行链接指定

2. << and +

运算符+的优先级高于左移<<

3.printf

%m.ns 输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的右侧,左补空格

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值