2016.9.4
分针和时针每隔(12/11)小时重合一次,一个钟面上分针和时针一昼夜重合(22)次
360 除以 (6-1/2) = 12/11小时
24除以12/11 = 22
本题考查钟表分针所转过的角度计算.钟表里的分钟与时针的转动问题本质上与行程问题中的两人追及问题非常相似.行程问题中的距离相当于这里的角度;行程问题中的速度相当于这里时(分)针的转动速度.
2016.8.16
和其他操作系统类似,Linux也支持两种进程:普通进程和实时进程。实时进程具有一定程度上的紧迫性,要求对外部事件做出非常快的响应;而普通进程则没有这种限制。所以,调度程序要区分对待这两种进程,通常,实时进程要比普通进程优先运行。这两种进程的区分也反映在task_struct数据结构中了。2016.8.25
在华为、中兴等企业招聘笔试面试中曾经出现过这样一道题目:什么函数不能声明为虚函数?
该题答案为:普通函数(非成员函数)、静态成员函数、内联成员函数、构造函数、友元函数
字符串转化成整数:
-
#include<stdio.h>
-
int strToInt(const char *str)
-
{
-
if (str == NULL)
-
return 0;
-
static const int MAX_INT =(int)((unsigned int)~0>>1);
-
static const int MIN_INT =-(int)((unsigned int)~0>>1)-1;
-
while (isspace(*str))
-
str++;
-
int sign = 1;
-
if (*str == '+' || *str == '-')
-
{
-
if (*str == '-')
-
sign = -1;
-
str++;
-
}
-
unsigned int n = 0;//这一这里的unsigned
-
while (isdigit(*str))
-
{
-
int c = *str - '0';
-
if (sign > 0 && (n > MAX_INT/10) || (n == MAX_INT/10 && c > MAX_INT % 10))
-
{
-
n = MAX_INT;
-
break;
-
}
-
if (sign < 0 && (n > (unsigned int)MIN_INT/10) || (n == MIN_INT/10 && c > (unsigned int)MIN_INT % 10))
-
{
-
n = MIN_INT;
-
break;
-
}
-
n = n*10 +c;
-
str++;
-
}
-
return sign > 0 ? n:-n;
-
}
-
int main()
-
{
-
char *str = "123";
-
printf("%d\n",strToInt(str));
-
return 0;
-
}
空结构体/类的大小为1。
微软笔试题:
what is the result of the follong program?
-
#include<iostream>
-
#include<malloc.h>
-
#include<string.h>
-
using namespace std;
-
char* f(char *str,char ch)
-
{
-
char *it1 = str;
-
char *it2 = str;
-
while (*it2 != '\0')
-
{
-
while (*it2 == ch)
-
{
-
it2++;
-
}
-
*it1++ = *it2++;
-
}
-
return str;
-
}
-
int main(int argc,char *argv[])
-
{
-
char *a = new char[10];
-
strcpy(a,"abcdcccd");
-
cout << f(a,'c');
-
delete[] a;
-
return 0;
-
}
答案是abddcccd
修改之后,上部分不变!
下面的程序输出是什么?(2010 网易)
-
int main()
-
{
-
int n;
-
char y[10] = "ntse";
-
char *x = y;
-
n = strlen(x);
-
*x = x[n];
-
x++;
-
printf("x = %s\n",x);
-
printf("y = %s\n",y);
-
return 0;
-
}
输出结果:
x = tse
y =
因为n=4,语句"n*x = x[n]"的功能是将x指向的第一个字符'\n'修改为'\0'。
assert宏的原型定义在中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:
#include <assert.h> void assert( int expression );
assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。
(2012 完美世界)
32位小端字节序的机器上,如下代码:
-
char array[12] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
-
short *pshort = (short *)array;
-
int *pint = (int *)array;
-
long long *pint64 = (long long *)array;
-
printf("0x%x,0x%x,0x%x,0x%x",*pshort,*(pshort+2),*pint64,*(pint+2))
输出结果为:0x201,0x605,0x4030201,0x8070605。
注解:printf是最右侧的元素先入栈,若入栈元素是char,short等小于4个字节的类型,入栈时也占4个字节。无符号时高位补1,有符号时,高位补符号位。大于4个字节时,如long long,则按实际字节数入栈。
-
std::string name1 = "youku";
-
const char *name2 = "youku";
-
char name3[] = {'y','o','u','k','u'};
-
size_t l1 = name1.size();//5
-
size_t l2 = strlen(name2);//5
-
size_t l3 = sizeof(name2);/4
-
size_t l4 = sizeof(name3);//5;
-
size_t l5 = strlen(name3);//?不确定
name3数组并未设置空字符,故strlen将数组name3后面的字符解释为数组中的字符,直到遇到空字符为止!!
c++空类默认产生哪些类成员函数:
class Empty
{
public:
Empty(); // 缺省构造函数
Empty( const Empty& ); // 拷贝构造函数
~Empty(); // 析构函数
Empty& operator=( const Empty& ); // 赋值运算符
Empty* operator&(); // 取址运算符
const Empty* operator&() const; // 取址运算符 const
};
默认构造函数
析构函数
拷贝构造函数
赋值运算符(operator=)
取址运算符(operator&)(一对,一个非const的,一个const的)
当然,所有这些只有当被需要才会产生。比如你定义了一个类,但从来定义过该类的对象,也没使用过该类型的函数参数,那么
基本啥也不会产生。在比如你从来没有进行过该类型对象之间的赋值,那么operator=不会被产生。
class Empty
{
public:
Empty(); // 缺省构造函数
Empty(const Empty&); // 拷贝构造函数
~Empty(); // 析构函数
Empty& perator=(const Empty&); // 赋值运算符
Empty* operator&(); // 取值运算符
const Empty* operator&() const; // 取值运算符
};
例如有以下class:
class StringBad
{
private :
char * str;
int len;
public :
StringBad( const char * s);
StringBad();
~ StringBad();
} ;
|
在构造函数和析构函数定义当中有如下定义:
StringBad::StringBad( const char * s)
{
len = std::strlen(s);
str = new char [len + 1 ];
}
StringBad::StringBad()
{
len = 4 ;
str = new char [ 4 ];
}
StringBad:: ~ StringBad()
{
delete [] str;
}
|
那么在程序当中如果有以下代码:
StringBad sports( " Spinach Leaves Bow1 for bollars " );
StringBad sailor = sports;
以上的第二条初始化语句将会调用什么构造函数?记住,这种形式的初始化等效于下面的语句:
StringBad sailor = StringBad(sports);
因为sports的类型为StringBad,因此相应的构造函数原型应该如下:
StringBad( const StringBad & );
当我们使用一个对象来初始化另一个对象时,编译器将自动生成上述构造函数(称为复制构造函数,因为它创建对象的一
个副本)。
现在我们来看看我们没有定义复制构造函数的情况下调用隐式复制构造函数将会出现什么情况。
从构造函数定义的代码片断可以看到,当中使用new操作符初始化了一个指针str,而隐式的复制构造函数是按值进行复制
的,那么对于指针str,将会进行如下复制:
sailor.str = sports.str;
这里复制的不是字符串,而是一个指向字符串的指针!也就是说,我们将得到两个指向同一个字符串的指针!由此会产生的
问题将不言而喻。当其中一个对象调用了 析构函数之后,其str指向的内存将被释放,这个时候我们如果调用另一个对象,其
str指向的地址数据会是什么?很明显将会出现不可预料的结果。
所以由此可见,如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据,而不是指针,
这被称为深度复制。因为默认的浅复制(或成为成员复制)仅浅浅的赋值指针信息。
我们再看以下代码片断,我们稍做修改:
StringBad headline1( " Celery Stalks at Midnight " );
StringBad knot;
knot = headline1;
这里的最后一行将与以上例子有所区别,现在是将已有对象赋给另一个已有对象,这将会采取其他操作,即使用重载的赋值
操作符。(我们需要知道的是:初始化总是会调用复制构造函数,而使用=操作符时也可能调用赋值操作符)因为允许对
象赋值,这是通过自动为类重载赋值操作符实现的。其原型如下:
Class_name & Class_name:: operator = ( const Class_name & );
它接受并返回一个指向类对象的引用。
与隐式的复制构造函数一样,隐式的对象赋值操作符也会产生同样的问题,即包含了使用new初始化的指针成员时,只会采
用浅复制。所以我们需要使用同样的解决办法,即定义一个重载的赋值操作符来实现深度复制。
所以综上所述,如果类中包含了使用new初始化的指针成员,我们应该显式定义一个复制构造函数和一个重载的赋值
操作符来实现其深度复制,避免由此带来的成员复制问题
1. 以下函数哪个是拷贝构造函数,为什么?
X::X(const X&);
X::X(X);
X::X(X&, int a=1);
X::X(X&, int a=1, b=2);
2. 一个类中可以存在多于一个的拷贝构造函数吗?
3. 写出以下程序段的输出结果, 并说明为什么? 如果你都能回答无误的话,那么你已经对拷贝构造函数有了相当的了解。
#include
#include
struct X {
template
X( T& ) { std::cout << "This is ctor." << std::endl; }
template
X& perator=( T& ) { std::cout << "This is ctor." << std::endl; }
};
void main() {
X a(5);
X b(10.5);
X c = a;
c = b;
}
|
解答如下:
1. 对于一个类X,如果一个构造函数的第一个参数是下列之一:
a) X&
b) const X&
c) volatile X&
d) const volatile X&
且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数。
X::X(const X&); //是拷贝构造函数
X::X(X&, int=1); //是拷贝构造函数
2.类中可以存在超过一个拷贝构造函数,
class X {
public:
X(const X&);
X(X&); // OK
};
|
注意,如果一个类中只存在一个参数为X&的拷贝构造函数,那么就不能使用const X或volatile X的对象实行拷贝初始化。
class X {
public:
X();
X(X&);
};
const X cx;
X x = cx; // error
|
如果一个类中没有定义拷贝构造函数,那么编译器会自动产生一个默认的拷贝构造函数。
这个默认的参数可能为X::X(const X&)或X::X(X&),由编译器根据上下文决定选择哪一个。
默认拷贝构造函数的行为如下:
默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造。
拷贝构造函数对类中每一个数据成员执行成员拷贝(memberwise Copy)的动作。
a)如果数据成员为某一个类的实例,那么调用此类的拷贝构造函数。
b)如果数据成员是一个数组,对数组的每一个执行按位拷贝。
c)如果数据成员是一个数量,如int,double,那么调用系统内建的赋值运算符对其进行赋值。
3. 拷贝构造函数不能由成员函数模版生成。
struct X {
template
X( const T& ); // NOT copy ctor, T can't be X
template
perator=( const T& ); // NOT copy ass't, T can't be X
};
|
原因很简单, 成员函数模版并不改变语言的规则,而语言的规则说,如果程序需要一个拷贝构造函数而你没