C/C++面试常见的几个库函数详解(strcpy,memcpy,memset,atoi...)

前言

在面试中,常常会被问到几个库函数的实现,虽然代码很短,涉及的细节却特别多,因此特别受面试官青睐,所以要把他们熟记于心,方能应对自如。

strcpy()

原型声明:char strcpy(char dest, const char *src); 
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间 
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 
返回指向dest的指针。

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <assert.h></span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *strcpy(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* dest, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *src) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//point1: 源字符串不改变,需要加const保证</span>
{
    assert(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span> != dest && <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span> != src); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//point2:保证指针有效</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> * temp = dest; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//point3:下面涉及到指针的移动,而我们需要返回dest的头指针,所以dest保留,而使用temp来移动</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> ((*temp++ = *src++) != <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\0'</span>); 
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* point4:末尾的'\0'也要复制过来
     * 上面先执行 *temp++ = *src++ ,再判断 *src 是否等于'\0'
     * 所以保证了'\0'先复制后判断
     */</span>
     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> dest; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//point5:返回dest头指针,支持链式表达式</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

链式的例子:

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> length = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strlen</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strcpy</span>(strA, strB));</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

strncpy()

strcpy()是一个高危函数,因为没有指定复制的大小,当dest的空间比src小时,就会出错,而我们没法进行控制。于是有了比较安全的strncpy():

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回dest。</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <assert.h></span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *strncpy(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>* dest, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *src, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> n)
{
    assert(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span> != dest && <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span> != src);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> * temp = dest;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (n-- > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> && (*temp++ = *src++) != <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\0'</span>); 
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 上面语句两种终止情况:
     * 1. n = 0,此时下面的语句也不执行,如果未达到src末尾
     * 不会自动在dest末尾添加'\0'的,所以需要使用者自己添加
     * 2. n > 0 但是src已经到达末尾,那么执行下面语句,将
     * dest填充'\0'达到长度n(ANSI C规定)
     */</span> 
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (n-- > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) *temp++ = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\0'</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> dest;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>

strcmp()

比较两个字符串 
设这两个字符串为str1,str2, 
若str1==str2,则返回零; 
若str1>str2,则返回正数; 
若str1

<code class="language-c hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#include <assert.h></span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strcmp</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *str1, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *str2)
{
    assert(NULL != str1 && NULL != str2);
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*不可用while(*str1++==*str2++)来比较,当不相等时仍会执行一次++,
    return返回的比较值实际上是下一个字符。应将++放到循环体中进行。*/</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span>(*str1 && *str2 && *str1 == *str2)
    {
        str1++;
        str2++;
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> *str1 - *str2;
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 若相等,则*str1 - *str2 = '\0' - '\0' = 0;
     * 否则,*str1 - *str2 != 0;
     * 因为前面的位都相等,所以只需要比较当前位来确定返回值
     */</span>
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

strcat()

把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)。

<code class="language-c hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strcat</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *dest,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *src)
{
    assert(NULL != dest && NULL != src);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *temp = dest;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\0'</span> != *temp) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//自增放在循环里,才可以覆盖'\0'</span>
        ++temp;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> ((*temp++ = *src++) != <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\0'</span>);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> dest;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>

strlen()

功能:计算给定字符串的(unsigned int型)长度,不包括’\0’在内 
说明:返回s的长度,不包括结束符NULL。

<code class="language-c hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strlen</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *s)
{
    assert(NULL != s);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> len = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (*s++ != <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\0'</span>)
        ++len;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> len;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

memset()

void *memset(void *s, int ch, size_t n);

函数解释:将s中前n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。 
memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。

注意,memset是以【字节】为单位进行赋值的,因此下面用法将导致错误:

<code class="language-c hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> arr[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>];
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memset</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">array</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(arr));</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>

arr指向5个字节的空间,每个都用ASCII为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个INT元素是4字节,合一起就是00000001000000010000000100000001,就等于16843009,就完成了对一个INT元素的赋值了。所以上面结果不是1而是16843009!

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *memset(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *s,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> c,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> n) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//point1:s指针类型未知,另外,n为字节数!</span>
{
    assert(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span> != s);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *temp = s;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (n--)
    {
        *(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *temp) = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span>)c; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//point2:转化为字符(1字节)</span>
        temp = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *)temp + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//point3:不能自增,因为不知道指针类型</span>
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> s;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

memcpy()

内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *memcpy(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *dest, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">const</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *src, size_t n)
{
    assert(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span> != dest && <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span> != src);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> *temp = dest;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (i < n)
    {
        *((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *)temp + i) = *((<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *)src + i); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//未知类型,不能自增</span>
        ++i;
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> dest;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

atoi()

这个函数就比较经典了,面试常常出现,因为可以考察各种特殊情况:空指针、空串、正负号、非法字符、溢出等等。

最大的int:0x7FFF FFFF; 
最小的int:0x8000 0000;

<code class="hljs axapta has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">enum</span> = {Invalid = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, Valid};
bool errno = Invalid;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> atoi(const <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> * <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>)
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> num = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//point1:可能溢出,所以用long long存</span>
    errno = Invalid;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (NULL != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> && *<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> != <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\0'</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//point2</span>
    {
        bool minus = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (*<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'+'</span>)
        {   
            ++<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>;
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (*<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'-'</span>)
        {
            ++<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>;
            minus = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\0'</span> != *<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//只有符号,Invalid</span>
            atoiCore(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>, minus, num);
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)num; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//已经检查过溢出,保证了num在int范围内    </span>
}

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> atoiCore(const <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> *<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>, bool minus, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> &num)
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\0'</span> != *<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (*<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> >= <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'0'</span> && *<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span> <= <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'9'</span>)
        {
            num = num*<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span> + (*<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>) - <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'0'</span>;
            ++<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ((!minus && num > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x7FFFFFFF</span>)||(minus && (-num) < (signed <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x80000000</span>))
            {
                errno = Invalid;
                num = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
            }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
        {
                errno = Invalid;
                num = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
        }
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (minus)
        num = -num;
    errno = Valid;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li></ul>

最后强调一遍,面试技术岗的,这几个函数一定要熟,一定要熟,一定要熟!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值