size_t strlen( const char *str )
{
size_t length = 0;
char *p = str; //保持str指向串首不变
while( *p++ )
++length;
return length;
}
char* strcpy( char *dest, const char *source )
{
assert( NULL != dest && NULL != source ); //对源地址和目的地址加非NULL断言
char *pd = dest;
char *ps = source;
while( *pd++ = *ps++ ); //先执行*,再执行赋值,再判断*pd,最后++. 所以退出循环前'\0'已被赋值
return dest;
}
void* memcpy( void *dest, const void *source, size_t n )
{
assert( NULL != dest && NULL != source ); //首先判断指针是否有效
char *pd = dest;
char *ps = source;
while( n-- > 0 )
*pd++ = *ps++;
return dest; //注意:返回的是原来的void* 类型的dest指针
}
void* memmove( void *dest, const void *source, size_t n )
{
assert( NULL != dest && NULL != source );
char *pd = dest;
char *ps = source;
if( pd < ps || ps + n -1 < pd ) //如果两块内存不重叠则正常操作
{
while( n-- )
{
*pd++ = *ps++;
}
}
else
{
pd += n - 1; //否则找到最后一个元素,反向操作
ps += n - 1;
while( n-- )
{
*pd-- = *ps--;
}
}
return dest;
}
char* strcat( char *str1, char *str2 )
{
assert( NULL != str1 && NULL != str2 );
char *p1 = str1;
char *p2 = str2;
while( *p1 ) p1++; //pd指向str1的'\n'
while( *p1++ = *p2++ ); //类似strcpy的操作
return str1;
}
int strcmp( const *str1, const *str2 )
{
assert( NULL != str1 && NULL != str2 );
char *p1 = str1;
char *p2 = str2;
while( *p1++ == *p2++ )//先执行*,然后==,然后运行循环体,最后++
{
if( *p1 == '\0' ) //其实此时:*p1 == *p2 == '\0',且之前的字符全相等
return 0;
}
return ( (*p1 < *p2) ? -1 : 1 ); //比较不相同字符间大小
}
char* strchr( const char *str, char ch )
{
char *p = str;
while( *p++ != '\0' )
{
if( *p == ch )
return p;
}
return ( *p == ch ? p : NULL ); //ch也有可能是'\0'
}
char* strstr( const char *str1, const char *str2 )
{
char *p = str1;
size_t len = strlen(str2);
while( *p++ != '\0' ) //p=strchr(p,*s2)
{
if( strncmp( p,str2,len ) == 0 )
return p;
}
return NULL;
}
void* memset( void *ptr, int ch, size_t n )
{
unsigned char c = ch;
unsigned char *p = ptr;
while( n-- )
{
*p++ = c;
}
return ptr;
}
************************* class string *************************
#include <iostream>
#include <"string.h"> //使用标准库函数
using namespace std;
class String
{
friend ostream& operator << ( ostream &os, String &str ); //友元函数
friend istream& operator >> ( istream &is, String &str );
public:
String();
String( char *s ); //使用字符串变量/常量初始化
String( const String &other ); //由于数据成员为指针,需自定义拷贝构造函数
~String(); //动态分配的内存空间,需手动释放
String& operator = ( const String &other );//this=other,返回this的引用
String operator + ( const String &other ); //new=this+other,返回函数中局部变量new
bool operator == ( const String &other ); //判断是否相等
char& operator [] ( unsigned int index ); //下标取值,返回字符的引用
size_t size(); //返回string的长度(不含'\0')
private:
char * ptr; //指针变量,用于指向动态存储空间中的字符数组
};
String::String()
{
ptr = NULL;
}
String::String( char *str )
{
size_t len = strlen(str);
ptr = new char[len+1]; //动态分配内存
strcpy( ptr, str );
}
String::String( const String &other )
{
size_t len = strlen(other.ptr);
ptr = new char[len+1]; //动态分配内存,深拷贝
strcpy( ptr, other.ptr );
}
String::~String()
{
if( ptr != NULL )
delete [] ptr; //释放堆空间(注意:采用new[]分配的空间必须采用delete[]释放)
ptr = NULL;
}
String& String::operator = ( const String &other )
{
if( this != &other )
{
if( ptr != NULL )
delete [] ptr; //释放原空间,再重新开辟
ptr = new char[strlen(other.ptr)+1];
stpcpy( ptr, other.ptr );
}
return *this; //返回String类型引用
}
String String::operator + ( const String &other )
{
String tmp; //局部变量,返回时复制给临时变量
tmp.ptr = new char[strlen(this.ptr)+strlen(other.ptr)+1];
strcpy( tmp.ptr, this.ptr );
strcat( tmp.ptr, other.ptr );
return tmp; //由于采用深拷贝,返回值传递过程都会重新开辟空间并复制,不会发生重复释放内存
}
bool String::operator == ( const String &other )
{
return (strcmp( this.ptr, other.ptr ) == 0); //采用string.h中的标准库函数实现
}
char& String::operator [] ( unsigned int index )
{
if( index >= 0 && index < strlen(this.ptr) )
return this.ptr[index]; //将String[]取值转换成了数组下标取值
}
size_t String::size()
{
return strlen(this.ptr);
}
ostream& operator << ( ostream &os, String &str )
{
os << str.ptr; //使用iostream类的<<函数
return os;
}
istream& operator >> ( istream &is, String &str )
{
char tmp[100]; //临时字符串数组
if( is >> tmp ) //如果有输入
{
delete [] str.ptr;
str.ptr = new char[strlen(tmp)+1];
strcpy( str.ptr, tmp );
}
return is;
}