文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>一些实现 memcpy strcpy atoi mems..

一些实现 memcpy strcpy atoi mems..

时间:2010-09-29  来源:Caterjava

C的几个库函数的实现  strcpy memcpy  atoi memset

(1) char* strcpy(char* strDest,const char* strSrc){

                    assert(strDest != NULL && strSrc != NULL);

                    char* strdestcopy = strDest;

                    while((*strDest++ = *strSrc++)  !=  '\0')

                               ;

                   return strdestcopy;

}

(2)安全版字符拷贝

char * __cdecl strncpy ( char * dest, const char * source, size_t count ) {            char *start = dest;            while (count && (*dest++ = *source++)) /* copy string */                        count--;            if (count) /* pad out with zeroes */                       while (--count)                                     *dest++ = '\0';            return(start); }   在 ANSI C 中,strcpy 的安全版本是 strncpy。
char *strncpy(char *s1, const char *s2, size_t n);
但 strncpy 其行为是很诡异的(不符合我们的通常习惯)。标准规定 n 并不是 sizeof(s1),而是要复制的 char 的个数。一个最常见的问题,就是 strncpy 并不帮你保证 \0 结束。
char buf[8];
strncpy( buf, "abcdefgh", 8 );
看这个程序,buf 将会被 "abcdefgh" 填满,但却没有 \0 结束符了。

另外,如果 s2 的内容比较少,而 n 又比较大的话,strncpy 将会把之间的空间都用 \0 填充。这又出现了一个效率上的问题,如下:
char buf[80];
strncpy( buf, "abcdefgh", 79 );
上面的 strncpy 会填写 79 个 char,而不仅仅是 "abcdefgh" 本身。

strncpy 的标准用法为:(手工写上 '\0')
strncpy(path, src, sizeof(path) - 1);
path[sizeof(path) - 1] = '\0';
len = strlen(path);
  内存拷贝

memcpy - Copy source buffer to destination buffer

 

;

 

;Purpose:

 

;       memcpy() copies a source memory buffer to a destination memory buffer.

 

;       This routine does NOT recognize overlapping buffers, and thus can lead
;       to propogation.

 

;       For cases where propogation must be avoided, memmove() must be used.

memmove - Copy source buffer to destination buffer
;
;Purpose:
;       memmove() copies a source memory buffer to a destination memory buffer.
;       This routine recognize overlapping buffers to avoid propogation.
;       For cases where propogation is not a problem, memcpy() can be used.

memcpy, 拷贝不重叠的内存块
void *memcpy(void* pvTo, void* pvFrom, size_t size)
{
           assert(pvTo != NULL && pvFrom != NULL);
           char* pbTo = (char*)pvTo;
           char* pbFrom = (char*)pvFrom;
          /* 内存块重叠吗?如果重叠,就使用memmove */
          assert(pbTo>=pbFrom+size || pbFrom>=pbTo+size);
          while(size-->0)
                   *pbTo++ == *pbFrom++;
          return pvTo;
}

void *MemCopy(void *dest,const void *src,size_t count)
{
    char *pDest=static_cast<char *>(dest);
    const char *pSrc=static_cast<const char *>(src);
    if( pDest>pSrc && pDest<pSrc+count )
    {
        for(size_t i=count-1; i<=0; ++i)
        {
            pDest[i]=pSrc[i];
        }
    }
    else
    {
        for(size_t i=0; i<count; ++i)
        {
             pDest[i]=pSrc[i];
        }
    }
    return pDest;
}

void* memmove(void *dest, const void *src,size_t n)
{
    if (n == 0) return 0;
    if (dest == NULL) return 0;
    if (src == NULL)    return 0;
    char *psrc = (char*)src;
    char *pdest = (char*)dest;
    if((dest <= psrc) || (pdest >= psrc + n)) /*检查是否有重叠问题 */
        {
         for(int i=0; i < n; i++) /*正向拷贝*/
          {
           *pdest = *psrc;
           psrc++;
           pdest++;
          }
        }
        else /*反向拷贝*/
        {
          psrc += n;
          pdest += n;
          for(int i=0;i<n;i++)
           {
            psrc--;
            pdest--;
            *pdest = *psrc;
           }
        }
   return dest;
}

memset:把buffer所指内存区域的前count个字节设置成字符c

void * Memset(void* buffer, int c, int count)
{
           char* pvTo=(char*)buffer;
           assert(buffer != NULL);
           while(count-->0)
          *pvTo++=(char)c;
           return buffer;
}

 

简单版的atoi实现

 

#include<iostream>

using namespace std;

int atio1(char *s)

{

    int sign=1,num=0;

    if(*s=='-')

        sign=-1;

    elseif(*s=='+')

        sign=1;

    s++;

    while((*s)!='\0')

    {

        num=num*10+(*s-'0');

        s++;

    }   

    return num*sign;   

}

该函数在如果是正数,且没有+号的情况下最高位被解掉了

 

int main()

{

    char *s="-123567890";   

    cout<<atio1(s);

    system("pause");

}

 

String类的设计

 

已知String类定义如下:

 

class String

{

public:

String(const char *str = NULL); // 通用构造函数

String(const String &another); // 拷贝构造函数

~ String(); // 析构函数

String & operater =(const String &rhs); // 赋值函数

private:

char *m_data; // 用于保存字符串

};

 

尝试写出类的成员函数实现。

 

答案:

 

String::String(const char *str)

{

            if ( str == NULL ) //strlen在参数为NULL时会抛异常才会有这步判断

                {

                  m_data = new char[1] ;

                  m_data[0] = '\0' ;

                }

               else

               {

                  m_data = new char[strlen(str) + 1];

                 strcpy(m_data,str);

              }

 }

 

String::String(const String &another)

{

         m_data = new char[strlen(another.m_data) + 1];

         strcpy(m_data,other.m_data);

}

 

 

String& String::operator =(const String &rhs)

{

             if ( this == &rhs)

                  return *this ;//在函数执行之前先做判断

            delete []m_data; //删除原来的数据,新开一块内存

            m_data = new char[strlen(rhs.m_data) + 1];

            strcpy(m_data,rhs.m_data);

            return *this ;

}

String::~String()

{

           delete []m_data ;

}

 

相关阅读 更多 +
排行榜 更多 +
野生恐龙射击生存安卓版

野生恐龙射击生存安卓版

飞行射击 下载
战场狙击手

战场狙击手

飞行射击 下载
1v1布娃娃射击安卓版

1v1布娃娃射击安卓版

飞行射击 下载