目录
1,求下面析构的顺序
2,以下调用了多少次拷贝构造
3,计算日期到天数的转换
4,日期差值
5,打印日期
6,累加天数
7,求1+2+3...n,要求不能使用乘除法、for、while、if、else、switch等关键字及判断语气
1,求下面析构的顺序
//1,求析构的顺序
C c;
int main()
{
A a;
B b;
static D d;
return 0;
}
答:静态对象在程序启动时被创建,并且其存储空间在整个程序的运行期间都存在。它们不依赖于特定的作用域,不会因为某个函数或代码块的结束而被销毁。
所以先析构局部的,再析构静态的
"对象创建时会调用构造函数来完成初始化。即便对象 d 是静态的,也是在程序执行到相应语句时才进行初始化"。
所以构造的顺序是 C A B D
析构先析构局部对象 A B,再析构静态对象 C D,先创建的后析构,后创建的先析构
所以析构的顺序是 B A D C
2,以下调用了多少次拷贝构造
class Weiget
{
public:
Weiget()
{}
Weiget(const Weiget& w)
{
cout << "Weiget(const Weiget& w)" << endl;
}
};
Weiget f(Weiget u)
{
Weiget v(u);
Weiget w = v;
return w;
}
int main()
{
Weiget x;
Weiget y = f(f(x));
return 0;
}
在做这个题目之前,我们先了解一段类似的代码,以下会进行几次拷贝构造
class A
{
public:
A()
{
}
A(const A& a)
{
cout << "A(const A& a)" << endl;
}
};
A f(const A a)
{
return a;
}
int main()
{
A a1;
A b = f(a1);
return 0;
}
在不考虑优化的情况下,这段代码中会执行三次拷贝构造函数。
第一次是在函数
f
调用时,将实参a1
传递给形参a
,会调用一次拷贝构造函数。第二次是在函数
f
中返回对象a
时,会调用一次拷贝构造函数。第三次是在
main
函数中,将函数f
的返回值赋给b
时,会调用一次拷贝构造函数。在一些编译器优化的情况下,第二次和第三次拷贝构造可能会合并成一次。返回的 a 时候又立马赋值给了对象 b,所以一些编译器可能会做优化。以避免不必要的拷贝操作,提高程序的性能。
有了上面的案例,我们做这个题就是信手拈来的事了
一共调用了 7 次拷贝构造,如果不做优化就是 9 次拷贝构造
3,计算日期到天数的转换
计算日期到天数转换_牛客题霸_牛客网
日期类中判断日期是否合法与这个题目类似
除掉本月外,计算每个月的天数相加,再加上本月的天数
#include <iostream>
using namespace std;
int GetMonthDays(int year, int month)
{
int MonthDays[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
if(month == 2 && (((year % 4 ==0)&&(year %100 !=0)) || year%400==0))
{
return 29;
}
return MonthDays[month];
}
int main()
{
int year,month,day;
cin >> year >> month >> day;
int days = 0;
for(int i = 1; i < month; ++i)
{
days += GetMonthDays(year,i);
}
days += day;
cout <<days <<endl;
}
4,日期差值
日期差值_牛客题霸_牛客网
我们先计算年,再算月份,最后算天数
年的天数:除掉该年,计算从 1 到该年之前的天数相加,闰年366,平年365
月的天数: 除本月,计算从1月到该月之前的月份天数相加,闰年2月29,平年28
天的天数:直接加上,最后还需要多加一天,因为题目说连续的日期算两天。
#include <iostream>
using namespace std;
bool isleapyear(int year)
{
if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
{
return true;
}
return false;
}
int SincetoBefore(int year,int month,int day)
{
int days = 0;
//加年的天数,从第一年开始加
for(int i = 1; i < year; ++i)
{
days += isleapyear(i) ? 366 : 365;
}
//加月份的天数
int Monthdays[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
for(int i = 1; i< month; ++i)
{
if(i == 2 && isleapyear(year))
{
days += Monthdays[i];
}
else
{
days += Monthdays[i];
}
}
//加天数
days += day;
return days;
}
int main()
{
int year1, month1, day1;
int year2, month2, day2;
scanf("%4d%2d%2d",&year1,&month1,&day1); //需要控制输入格式
scanf("%4d%2d%2d",&year2,&month2,&day2);
int days1 = SincetoBefore(year1,month1,day1);
int days2 = SincetoBefore(year2,month2,day2);
int day = days1 > days2 ? days1-days2 +1 : days2 -days1+1; //输出的时候需要多加一天,题目说连续的日期算两天
cout << day << endl;
}
5,打印日期
打印日期_牛客题霸_牛客网
相对于就是把天数转成日期
1,计算月份,和剩余的天数,不断减,直到这个天数小于该月的天数,这和日期类中的日期加天数类似
2,我们有三个变量年、月、日 需要打印,所以我就用了一个简单的日期类打印,直接传值过去打印
#include <iostream>
using namespace std;
//日期类实现打印功能
class Date
{
public:
Date(int year = 0,int month = 1,int day = 1)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
if(this->_month> 9 && this->_day > 9)
cout << _year <<"-"<<_month <<"-"<<_day <<endl;
else if(this->_month > 9 && this->_day <=9)
cout << _year <<"-"<<_month <<"-0"<<_day <<endl;
else if(this->_month <= 9 && this->_day >9)
cout << _year <<"-0"<<_month <<"-"<<_day <<endl;
else
cout <<_year << "-0" <<_month <<"-0" <<_day;
}
private:
int _year;
int _month;
int _day;
};
//计算出月份和剩的天数
void Date_Print(int year, int days)
{
int month = 1;
int monthDays[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
while(days > monthDays[month])
{
if(month == 2 &&(((year % 4 == 0)&&(year%100!=0)) ||year %400 == 0))
days -= 29;
else
days -= monthDays[month];
++month;
//月超出了1月,年进位,月置成 1
if(month == 13)
{
++year;
month = 1;
}
}
Date d1(year,month,days); //把年月日,传给日期类打印
d1.Print();
}
int main()
{
int year = 0;
int days = 0;
while (cin>>year>>days)
{
Date_Print(year,days);
}
return 0;
}
6,累加天数
日期累加_牛客题霸_牛客网
与日期类中日期加天数类似
#include <iostream>
using namespace std;
class Date
{
public:
Date(int year = 0, int month = 1, int day = 1)
:_year(year)
,_month(month)
,_day(day)
{}
//日期累加
Date& calculateDate(int days)
{
_day += days;
int Monthdays[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
while (_day > Monthdays[_month])
{
if(_month == 2 && ((_year % 4 == 0 && _year % 100 != 0)
||( _year %400 ==0)))
{
_day -= 29;
}
else
{
_day -= Monthdays[_month];
}
++_month;
if(_month == 13)
{
++_year;
_month = 1;
}
}
return *this;
}
//打印
void Print()
{
printf("%d-%02d-%02d\n", _year, _month, _day);
}
private:
int _year;
int _month;
int _day;
};
int main()
{
int m = 0;
cin >> m;
int year, month, day, days;
for(int i = 0; i< m; ++i)
{
cin >> year >> month >> day >> days;
Date d(year,month,day);
d.calculateDate(days);
d.Print();
}
}
7,求1+2+3...n,要求不能使用乘除法、for、while、if、else、switch等关键字及判断语气
求1+2+3+...+n_牛客题霸_牛客网
把 _sum 和 _i 设置成静态的变量,这样就属于所有的对象,而不是属于某个对象
Sum* p = new Sum[n]; n是几就会调用几次构造函数,相对于是一个数组,数组里面存的
是对象,n 是几就表示有几个对象,对象在创建的时候就会自动调用构造函数完成初始化
class Sum
{
public:
Sum()
{
_sum += _i;
++_i;
}
static int GetNum()
{
return _sum;
}
private:
static int _sum;
static int _i;
};
int Sum::_sum = 0;
int Sum::_i = 1;
class Solution {
public:
int Sum_Solution(int n)
{
Sum* p = new Sum[n];
return Sum::GetNum();
}
};