int main(void)
{
printf("%s , %5.3s\n","computer","computer");
return 0;
}
输出
computer , com
%m.ns 输出占m列,但只取字符串中左端n个字符。这n个字符输出在m列的右侧,左补空格。
2、
虚函数动态绑定
动态联编就是程序在运行的时候知道该调用哪个函数,而不是编译阶段,所以这个机制应该是由虚函数支持的,即运行时的多态,基类的某个成员函数声明为虚函数,派生类继承,而且同样重写该函数,那么当声明一个派生类的指针或者引用时,它所调用的函数是由该指针指向的对象确定的,这就是动态联编
3、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class parent
{
public :
virtual void output();
};
void parent::output()
{
printf( "parent!" );
}
class son
: public parent
{
public :
virtual void output();
};
void son::output()
{
printf( "son!" );
} |
1 2 3 4 | son
s; memset(&s
, 0 ,
sizeof(s)); parent&
p = s; p.output(); |
没有输出结果,程序运行出错
4、
C++ 类占用空间计算方式
1、一个类占用的空间主要是属性占用空间,而成员函数一般不占用空间,但是虚函数占用空间,需要说明的是,无论多少个虚函数,只要占用4个字节即可,也就是索引指向一个虚拟表的首位置。另外需要说明的是占用空间都考虑了对齐,所以不足4个的按照满4个的算。
2、类的继承,子类占用空间是父类基础上增加本类空间即可。所以说可以认为,子类就是直接拷贝了父类的内容,然后结合自身的内容。而且存储空间也是这个顺序,即先父类分配空间,然后才是子类空间。
3、静态成员变量不占用类空间,应该是确实没有放入这个类的里面,而且没有指针指向它,只能通过类::来访问,也就是说静态成员是随着类的存在而存在,而 不依赖于对象,它的存在意义主要还是区分,否则如何确定其意义,这还是体现了相关的都方一起的思想,比全局变量或者常量更方便使用和理解。
4、需要说明的是,虚函数对应的虚拟表在空间的其他位置,和对象是没有联系的,但是虚拟表地址是和类统一的,也就是说一旦确定,无论在哪个对象中,其指针 值是一样的,即虚拟表位置是一定的。指针放在对象的最前面,首先是指向虚函数的虚拟表指针,然后才是其他成员变量空间。
5、
我认为浅拷贝是一个不喜欢思考的懒汉,而深拷贝则是一个思维严谨,喜欢思考的人。对于懒汉来说,虽然给了他任务,但是他总是想尽量的少做一些事情,所以很多时候做出来的东西就是只看到了表面,不会去思考对不对。
struct X { int x; int y; };
对于懒汉来说,他很直白的看到了x,看到了y,然后就拷贝x和y,然后就不管了,反正我完成我的拷贝了,至于对不对,我不管。
而一旦有了引用或者指针,事情就不一样了
struct X { int x; int y; int* p; };
int *p = new int(47); int *q = p;
如q与p都是指向一个物体一样。
那么如果原来的物体销毁了,但是现在拷贝的物体还在,那么这时候你拷贝后的物体的成员指针就是一个悬挂指针,指向了不再存在的物体,那么你访问的话,那就不知道会发生什么了。
而对于深拷贝,这一个勤奋的人,他不会只做表面,他会把每一个细节都照顾好。于是,当他遇到指针的时候,他会知道new出来一块新的内存,然后把原来指针指向的值拿过来,这样才是真正的完成了克隆体和原来的物体的完美分离,如果物体比作人的话,那么原来的人的每一根毛细血管都被完美的拷贝了过来,而绝非只是表面。所以,这样的代价会比浅拷贝耗费的精力更大,付出的努力更多,但是是值得的。当原来的物体销毁后,克隆体也可以活的很好。
然而事实上是这个世界上大多都是懒汉,包括编程的人,编译器等,所以默认的行为都是浅拷贝,于是有时候你需要做一个勤奋的人,让事情做正确,自己去完成深拷贝所需要的事情。
6、
7、
如果 const 位于 * 的左侧,则 const 就是用来修饰指针所指向的变量,即指针指向为常量;
如果 const 位于 * 的右侧, const 就是修饰指针本身,即指针本身是常量。
8、
9、
浮点数判断是否为0
float : const EXPRESSION EXP = 0.000001
if ( a < EXP && a >-EXP)
10.
32位系统中,定义**a[3][4],则变量占用内存空间为 48bytes
**a[3][4]存储的是指向地址的二维指针数组,32位系统一个地址4个字节,12*4=48byte
11.
在VC6.0中,stack的大小一般为2M,不会自动增加。stack一般存放函数的参数列表、返回值、局部变量。
stack 不存储全局变量的值的值
13、下列哪些http方法对于服务端和用户端一定是安全的?
HEAD,GET,OPTIONS和TRACE视为安全的方法,因为它们只是从服务器获得资源而不对服务器做任何修改,但是HEAD,GET,OPTIONS在用户端不安全。而POST,PUT,DELETE和PATCH则影响服务器上的资源。
TRACE: 这个方法用于返回到达最后服务器的请求的报文,这个方法对服务器和客户端都没有什么危险。OPTIONS:列出请求的资源所支持的所有方法。
14、下面函数的时间复杂度是
long foo(long x){
if(x<2) return 1;
return x*x*foo(x-1);
}
将这个递归转换成循环的形式,其实就是一层的循环,所有时间复杂度为O(N)
15、一棵非空的二叉树的先序遍历序列与后序遍历序列正好相反,则该二叉树一定满足?
只有一个叶子结点
16、HTTPS是使用( )来保证信息安全的.
SSL
17、1.不建议在构造函数中抛出异常;
2.构造函数抛出异常时,析构函数将不会被执行,需要手动的去释放内存
1.析构函数不应该抛出异常;
2.当析构函数中会有一些可能发生异常时,那么就必须要把这种可能发生的异常完全封装在析构函数内部,决不能让它抛出函数之外;
3. 析构函数异常相对要复杂一些,存在一种冲突状态,程序将直接崩溃:异常的被称为“栈展开(stack unwinding)”【备注】的过程中时,从析构函数抛出异常,C++运行时系统会处于无法决断的境遇,因此C++语言担保,当处于这一点时,会调用 terminate()来杀死进程。因此,当处理另一个异常的过程中时,不要从析构函数抛出异常, 抛出异常时,其子对象将被逆序析构
18、
对于满足SQL92标准的SQL语句:
select foo,count(foo)from pokes where foo>10group by foo having count (*)>5 order by foo
其执行顺序应该是?
FROM->WHERE->GROUP BY->HAVING->SELECT->ORDER BY
19、在网络7层协议中,如果想使用UDP协议达到TCP协议的效果,可以在哪层做文章?
会话层
20、struct以最长的基本类型对齐。
21、开发C代码时,经常见到如下类型的结构体定义:
typedef struct list_t{
struct list_t *next;
struct list_t *prev;
char data[0];
}list_t;
最后一行char data[0];的作用是?
A方便管理内存缓冲区
B减少内存碎片化
开发C代码时,经常见到如下类型的结构体定义:
typedef struct list_t{
struct list_t *next;
struct list_t *prev;
char data[0];
}list_t;
最后一行char data[0];的作用是?