C++面接でよく聞くライブラリ関数


1 memset()
大きな構造体または配列をゼロにする最も速い方法です.
関数宣言:
void *memset(void *s, int ch, size_t n);

sの最初のnバイト(typedef unsigned int size_t)をchで置き換え、sを返します.
void*  memset(void *src, int c, size_t size)
{
    assert(src != NULL);
    char *pSrc = (char *)src;
    while (size--)
    {
        *pSrc++ = (char)c; //   char
    }
    return src;
}

2 memcpy()
ソースsrcが指すメモリアドレスの開始位置からnバイトをターゲットdestが指すメモリアドレスの開始位置にコピーします.
  • memcpyの関数では、ソースアドレスポインタ、ターゲットアドレスポインタ、戻りアドレスポインタがvoidタイプです.voidタイプのポインタもメモリアドレスを指すが、このアドレスユニット内のデータタイプを指定せず、間接的にメモリ内のデータにアクセスすることはできず、他のタイプのポインタに値を割り当てることもできず、アルゴリズム操作もできない.したがってvoidポインタはp++のような操作はできないので、char*のような特定のタイプのポインタに変換して操作する必要がある.
  • メモリが重複する問題:コピー時に2つのアドレスのメモリが上書きされている可能性があります.この場合、後から前へコピーすればいいです.メモリのオーバーラップを判断するには、ソースアドレスポインタとターゲットアドレスポインタのsize範囲内のサイズを比較するだけです.
  • memcpyはメモリのオーバーラップを処理できないと言われています.memmoveはメモリのオーバーライドを処理できます.anyway、C++11の下でmemcpyがメモリのオーバーライドを処理できることを発見しました.
  • #include 
    #include 
    #include 
    //const  
    void *Memcpy(void *dst, const void *src, size_t size);
    
    int main(int argc, char *argv[])
    {
        char buf[100] = "abcdefghijk";
        //memcpy(buf+2, buf, 5);
        Memcpy(buf+2, buf, 5);
        printf("%s
    "
    , buf+2); } void *Memcpy(void *dst, const void *src, size_t size) { char *psrc; char *pdst; if(NULL == dst || NULL == src) { return NULL; } if((src < dst) && (char *)src + size > (char *)dst) // { psrc = (char *)src + size - 1; pdst = (char *)dst + size - 1; while(size--) { *pdst-- = *psrc--; } } else { psrc = (char *)src; pdst = (char *)dst; while(size--) { *pdst++ = *psrc++; } } return dst; }

    3 strcpy()
    srcアドレスから始まりNULL終端子を含む文字列がdst開始のアドレス空間にコピーされ、dstへのポインタが返されます.
    strcpyはC言語の標準ライブラリ関数です.strcpyを使用するには、次のヘッダファイルが必要です.
    #include 
    #include 

    コード:
    char* strcpy(char* dst , char* src){
        if(dst==NULL||src==NULL) return NULL;// --1
        if(dst==src) return dst;    //--2
        char* address = dst;    //--3
        while((*dst++ = *src++)!='\0') //--4
        return address;     //--5
    }

    図に落札されたのはすべて試験点で、以下は一つ一つ説明します.
    1、パラメータの正しさを判断する必要があります.ここでは異常を投げ出すこともできます.2、同じメモリを指している場合は、コピーせずに直接戻ることができます.3、ここでは元のdstポインタを保存し、戻り値4として使用する必要があります.ここでは、次の2つを書くと、面接の際に大幅に減点されます.
    //   
    while(*dst++ = *src++)  //      ,          
    //   
    while(*src!='\0'){*dst++ = *src++;}//   src     ,   dst    '\0',   dst         

    5、関数がdstの元の値を返すのは、チェーン式をサポートするためであり、関数の付加性が増加する.
    では、srcの元の値を返さない理由を尋ねることもあります.
    ソース文字列はもともと知られており、char*strA=strcpy(new char[10],strB)のような表現をサポートできない意味はありません.ソース文字列を保護するために、constを使用してsrcが指す内容を限定し、const charをcharの戻り値とし、タイプが一致せず、コンパイラがエラーを報告します.
    strcpyとmemcpyの違い:
    コピー内容が異なります:strcpyは文字列しかコピーできませんが、memcpyは文字配列、整数、構造体などのコピー方法が異なります.strcpyは長さを指定する必要はありません.文字列終端記号'0'に遭遇してから終了するので、オーバーフローしやすいです.memcpyでは、長さの用途が異なることを指定するために3番目のパラメータを入力する必要があります.通常、文字列をコピーするときはstrcpyを使用し、他のデータ型をコピーする必要があるときはmemcpyを使用します.
    参照先:http://www.developersite.org/906-20054-CC++%E7%9A%84mem%E5%87%BD%E6%95%B0%E5%92%8Cstrcpy%E5%87%BD%E6%95%B0%E7%9A%84
    4 strncpy()
    strcpy()は、レプリケーションのサイズが指定されていないため、destの空間がsrcより小さい場合にエラーが発生する高危険関数です.関数strncpyがありますstrncpyは、srcの終端子'0'に遭遇しなくても、文字列のコピー時にsize文字を最大でコピーします.次に、srcが指す文字列のうちsrcアドレスで始まる前のnバイトをdestが指す配列にコピーし、destを返します.
    char* strncpy(char *dst, const char *src, size_t size)
    {
        if(dst==NULL||src==NULL) return NULL;// --1
        char *add = dst;//      
        while (n-- > 0 && (*temp++ = *src++) != '\0'); 
        /*           :
         * 1. n = 0,           ,     src  
         *      dest    '\0' ,           
         * 2. n > 0   src      ,        , 
         * dest  '\0'    n(ANSI C  )
         */ 
        while (n-- > 0) *temp++ = '\0';
        return tmp;
    }

    5 strlen()
    与えられた文字列の長さを計算し、'0'を含まない
    unsigned int strlen(const char *s)
    {
        assert(NULL != s);
        unsigned int len = 0;
        while (*s++ != '\0')
            ++len;
        return len;
    }

    6 strcmp()
    #include 
    int strcmp(const char *str1, const char *str2)
    {
        assert(NULL != str1 && NULL != str2);
        /*   while(*str1++==*str2++)   ,           ++,return               。  ++        。*/
        while(*str1 && *str2 && *str1 == *str2)
        {
            str1++;
            str2++;
        }
        return *str1 - *str2;
        /*    , *str1 - *str2 = '\0' - '\0' = 0;
         *   ,*str1 - *str2 != 0;
         *          ,                
         */
    }

    7 atoi()
    文字列を整数に変換:1.文字列の先頭がスペースの場合、すべてのスペースをスキップし、最初の非スペース文字に、ない場合は0を返します.2.最初の非スペース文字が記号+/-である場合、signの真偽をマークする.3.次の文字が数字でない場合は0を返します.4.次の文字が数字であれば整形して保存し、次に非数字が現れると現在の結果を返します.5.整形数の範囲を超えた場合、現在の値の代わりに境界値を使用する境界問題も考慮する必要があります.
    class Solution {
    public:
        int myAtoi(string str) {
            if (str.empty()) return 0;
            //1 sign initial as 1, n initial as str.size()
            int sign = 1, base = 0, i = 0, n = str.size();
           //2 i < n
            while (i < n && str[i] == ' ') ++i;
            if (str[i] == '+' || str[i] == '-') {
                sign = (str[i++] == '+') ? 1 : -1;
            }//3 i++
            while (i < n && str[i] >= '0' && str[i] <= '9') {
                if (base > INT_MAX / 10 || (base == INT_MAX / 10 && str[i] - '0' > 7)) {
                //5 INT_MAX or INT_MIN
                    return (sign == 1) ? INT_MAX : INT_MIN;
                }
                base = 10 * base + (str[i++] - '0');
            }
            //4 base * sign
            return base * sign;
        }
    };

    参考資料:http://blog.csdn.net/jiange_zh/article/details/50802044#t7