22、以去除最后一位,以n=3657为例。
由此图可见,由string指向应填入的字符数组的相应位置。
由调用的最底层开始,回归时填入,每次回归,指针后移一位,由此得
char * itoal(int n,char *string){
if(n/10) string=itoal(n/10,string);
*string++=n%10+48;//字符,ASCII码
return string;
}
考虑,数字串结束符和负数,得完整的函数。
char * itoal(int n, char *string){
if(n<0){
*string++=’_’;
23、 n=-n;
}
if(n/10)string=itoal(n/10,string);
*string++=n%10+48;
*string=’\0’;
return string;
}
源代码:
#include
using namespace std;
char* reverse (char* s){
char temp,* temp1=s,* temp2=s;
while(*temp2) temp2++;
temp2--;//指针移回串尾
while(temp2-temp1>0){//注意此处,从串两头的指针同时向中间移动,
24、重合或交错时停止
temp=*temp1;
*temp1=*temp2;
*temp2=temp;
temp1++;
temp2--;
}
return s;
}
char *itoa (int n,char *string){
char *temp=string;
if(n<0){
*temp++='-';
n=-n;
}
do{//注意个位放在前了
*temp++=n%10+48;
}while(n=n/10);//显式的循环
*temp='\0';
if(*string=='-') temp=stri
25、ng+1;//有负号仅反转数字部分
else temp=string;
reverse(temp);//个位放到后面
return string;
}
char *itoa1 (int n,char *string){
if(n<0){
*string++='-';
n=-n;
}
if(n/10) string=itoa1(n/10,string);//隐式循环
*string++=n%10+48;
//第一次是数字最高位放串的最前面的字符(不含符号),注意指针移动在后
*string='\0';
return string;//注意返回
26、的指针已后移一字符
}
char *itoa0 (int n,char *string){
itoa1(n,string);
return string;
}
int main(){
int num;
char st[20];
cin>>num;
cout<<"输出数字串:"<>num;
cout<<"输出数字串:"<中定义一个日期时间的结构:
struct tm{
int tm_sec
27、 //秒
int tm_min; //分
int tm_hour; //时
int tm_mday; //日
int tm_mon; //月
int tm_year; //年,实际放的是与1970年的差,如1990年为20
int tm_wday; //星期
int tm_yday; //一年中的第几天
int tm_isdst; //是否夏时制
};
函数 time_t time(time_t *tp)是提取当前时间,time_t即长整型,代表从1970年1月1日00:00:00开始计算的秒数(格林尼治时间),放在首地址为tp的单元内。
28、
函数 tm *localtime(const time_t *tp) 将tp地址单元中的时间转换为日期时间结构的当地时间;(函数 tm *gmtime(const time_t *tp)转换为日期时间结构的格林尼治时间;)
函数 char *asctime(tm *tb)将tb地址单元中的tm结构的日期时间转换为字符串(供显示),它有固有格式,如:
Sun Sep 16 01:03:52 1973
利用以上资源,重新设计一个日期时间类(DataTime),要求定义对象时取当前时间进行初始化,显示时重取显示时刻的时间并显示出来。
解:
#include29、ream>
#include
using namespace std;
class datatime{
tm *timedata;
long allsecond;
char *tmp;
public:
datatime(){
time(&allsecond);
timedata=localtime(&allsecond);
tmp=asctime(timedata);
cout<30、ata=localtime(&allsecond);
tmp=asctime(timedata);
cout<>ch;
if(ch=='y'||'Y') dt.gettime();
return 0;
}
5.11 完善自定义字符串类mystring,函数包括:构造函数、拷贝构造函数、析构函数,并重载运算符[ ],=(分别用mystring和C字符串拷贝),+(
31、strcat),+=,<,==(strcmp)。
解: 此例既是对第4章的复习也是一个提高。拷贝构造函数的应用请参阅4.4.2节末尾两项说明,本例形参使用引用,仅在返回时调用了拷贝构造函数。运算符的重载请参阅4.5节。
#include
using namespace std;
const int n=256;
class mystring{
char str[n]; //存放字符串的数组容器
int maxsize; //最大可用元素数,可防止数组出界,提高健壮性
int last; //已用
32、元素最大下标
public:
mystring(){
last=0;
maxsize=n;
str[0]='\0';
cout<<"缺省构造函数"<33、数"<34、erator[](int i){ //返回引用,可读可写
if(i>last) last=i; //下标运算符,可添加长度但不查边界
return str[i];
}
mystring operator=(mystring &);
mystring & operator=(char * ms);//这里重载的=是把C风格字符串赋给mystring
mystring operator+(mystring &);
mystring operator+=(mystring &);
bool operator<(mystring &);
bool o
35、perator==(mystring &);
};
mystring mystring::operator=(mystring & ms){
last=-1;
do{
last++;
str[last]=ms.str[last];
}while(last36、last]!='\0'&&last37、last&& temp.last38、 str[last] ='\0'; //截尾处理时,必须加串结束符
return *this;
}
bool mystring::operator<(mystring & ms){ //重载<运算符
int i=0,k;
do{
k=str[i]-ms.str[i];
i++;
}while(k==0&&i39、ystring & ms){
int i=0,k;
if(last!=ms.last) return false;
do{
k=str[i]-ms.str[i];
i++;
}while(k==0&&i40、函数生成
mystring ms4(ms3),ms5=ms3,ms6; //ms4,ms5用拷贝构造函数生成;ms6用缺省构造函数
ms6=sp4; //ms6赋值是返回引用,不用拷贝构造函数
ms1.show();
ms2.show();
ms3.show();
ms4.show();
ms5.show();
ms6.show();
ms4=ms1+ms2+ms6;//注意temp和临时变量由拷贝构造函数生成
ms4.show();
ms1+=ms2+=ms3;
ms1.show();
if(ms141、t<<"应排在"<42、]='.';//写入
ms1[i]='\0';
i=0;
ms1.show();
return 0;
}
5.12 将习题5.8中的字符串处理函数移植到mystring类中,其中strcat已重载为+运算符,
请将其它4个转为成员函数。对比成员函数与独立函数构造上有何不同?
解:这四个函数因mystring内部有串长,又要求下标索引,再加上str字符数组可直接使用,构造大不相同。
#include
using namespace std;
const int n=256;
class mystring{
char str[n];
43、 //存放字符串的数组容器
int maxsize; //最大可用元素数,可防止数组出界,提高健壮性
int last; //已用元素最大下标
public:
mystring(){
last=-1;
maxsize=n;
str[0]='\0';
cout<<"缺省构造函数"<44、[last];
}while(s[last]!='\0'&&last45、ndl;
}
void show(){//如需重载<<,则参见9.3.3节,暂时未学到,替代方法是用show()函数
cout<last) last=i; //下标运算符,可添加长度但不查边界
return str[i];
}
my
46、string & operator=(mystring &);
mystring & operator=(char * ms);//这里重载的=是把C风格字符串赋给mystring
mystring operator+(mystring &); //这里返回不能用引用
mystring & operator+=(mystring &);
bool operator<(mystring &);
bool operator==(mystring &);
};
void mystring::reverse(){
int i=0,j=last-1;
char temp;
47、
while(j>i){//注意此处,从串两头同时向中间移动,重合或交错时停止
temp=str[i]; //头尾交换
str[i]=str[j];
str[j]=temp;
i++;
j--;
}
}
int mystring::strchr(char c){
int i;
for(i=0;i!=last;i++) if(str[i]==c) return i;
return -1; //未找到返回-1
}
int mystring::strstr(mystring str1){
int i=0,k=1;
while(str[
48、i]!='\0'){//只要主串还有字符未查,则继续
while(str[i]!=str1[0]&&str[i]!='\0') i++;//找到主串含有子串的第一个字符,或主串查完停止
if(str[i]!='\0'){//核对子串其他字符
while(str[i+k]==str1.str[k]&&k49、g::operator=(mystring & ms){//这里返回值改为引用,不调用拷贝构造函数
last=-1;
do{
last++;
str[last]=ms.str[last];
}while(last50、ze-1);
str[last] ='\0'; //截尾处理时,必须加串结束符
return *this;
}
mystring mystring::operator+(mystring & ms){//注意+和+=的不同
mystring temp(*this);//+必须在一份拷贝上进行
int i=-1;
temp.last--;//串的结尾是结束符,连接时要覆盖掉
do{
temp.last++;
i++;
temp.str[temp.last]=ms.str[i];
}while(i