strncpy 和 memcpy 的区别

昨天仙儿去面试,告诉我他被问到这样一个题目。很遗憾尽管这两个函数是如此简单常用,而我也回答错了。换句话说如果我去回答我也会被鄙视的。我以为既然有人这样问,那么可能在内存重叠时可能会不一样,然而我回去查了下 msdn 发现两者对于内存重叠都是未定义行为,所以内存重叠时应该使用 memmove,而不是 memcpy。

        那么两者的区别在哪里呢,首先我们忽略参数的类型差别(前者明确要求 char*,后者无要求),因为这个差别非常的无关紧要。答案就是:当拷贝的字节数小于等于字符串长度时,两者的结果是等效的。但当拷贝的字节数大于字符串长度时,strncpy 是用 0 去补齐字节数,而不是取自于 source。而 memcpy 呢,显然是完全不 care 它拷贝是什么内容的。

        下面我可以通过一段测试代码给出直观的对比:

 

#include <string.h>
#include <stdio.h>

void printBytes(char *s, int count)
{
    int i;
    for(i = 0; i < count; i++)
    {
        _tprintf(_T("%02X "), s);

        if((i & 0xF) == 0xF)
            _tprintf(_T("\n"));
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    int i;
    char src[16], dest[16];
    memset(src, 0sizeof(src));
    strcpy(src, "abc");
    strcpy(src + 4"defg");

    _tprintf(_T("strncpy:\n"));
    strncpy(dest, src, 8);
    printBytes(dest, 8);

    _tprintf(_T("\nmemcpy:\n"));
    memcpy(dest, src, 8);
    printBytes(dest, 8);
    _tprintf(_T("\n"));

    getchar();
    return 0;
}


        当然了,上面的准备 src 的那两行代码也可以这样写:

        strcpy(src, "abcdefgh"); 
        src[3] = 0; 

        代码输出如下(红色数字标记出了两者的行为差异):

 

strncpy:
61 62 63 00 00 00 00 00
memcpy:
61 62 63 00 64 65 66 67


        可以注意到 strncpy 是需要关注字符串的内容的,所以一旦遇到0以后,后面被拷贝的字节就全部是 0。而 memcpy 是不关注被拷贝的内容是什么的,因此从这个角度来说,无论如何,memcpy 都会比 strncpy 高效一点。

        最后我们还需要特别提一点别的,strncpy 在被拷贝的字节数小于字符串长度时,是不负责在结尾添加 null-terminator 字符的,所以这时候字符串可能没有结尾。另外两者对于内存重叠都没有做考虑。当 dest 的地址稍微小于 src 的地址时,可能不会出现问题。当 dest 稍微大于 src 时,因为src 可能被覆盖,所以导致结果有问题。

        你不能抱怨面试者为什么要出这样一个问题,即使你平时已经无数次的使用过这两个基本的函数。然而如果你不能给出正确回答,那么结论就是,你对这样基本的函数例如 strncpy 的了解不够彻底导致的。所以归结于自己的问题。

        昨天和火车上的一个说英语的中国人(他的母亲是中国人)聊了一路一个多小时的英文,哈哈,这还是我第一次在生活中用英文和别人对话这么长时间。我发现很多很简单的单词我当时居然没有想起来,直到事后我才反应过来,因为当你对话时,你是没时间停下来思考这些最简单的单词是什么的,就好像大脑短路了。例如:

        缺点:shortcoming;当时我用了flaw。
        目的:aim;当时我用了purpose。
        原则:principle。
        术语:terminology,这个词我都忘了怎么拼了,是临时查字典查的。
        自大:这个词我不知道用什么单词。
        
        这些都是我事后才想起来,当时想提到这些时居然会卡壳。。。我们从简体繁体中文聊到技术(因为我知道对方不是技术人员,所以我其实克制了自己在技术方面去展开,只是给他讲到了 C++ 是学习起来比较难的一门语言,以及代码可读性和运行效率之间的关系)聊到中国的问题,聊到房价,租房,政治等等,同时我也给他普及了诸如”80后“,”屌丝“,”富二代“这些术语。他还夸奖我说我的英文在中国人中比较少见的说的比较流利。这次经历主要是对于我说英文是个鼓励,另外也更加让我认识到要继续提高词汇量的重要性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值