设为首页 收藏本站
查看: 143|回复: 0

[经验分享] C++面试八股文:如何实现一个strncpy函数?

[复制链接]
累计签到:50 天
连续签到:1 天
发表于 2025-2-11 13:20:03 | 显示全部楼层 |阅读模式
某日二师兄参加XXX科技公司的C++工程师开发岗位第31面:
面试官:strcpy函数使用过吧?
二师兄:用过。
面试官:这个函数有什么作用?
二师兄:主要用做字符串复制,将于字符从一个位置复制到另一个位置。
面试官:strncpy函数也使用过吧,和strcpy有何不同?
二师兄:strncpy多了一个size_t的参数,用于避免缓冲区溢出。
面试官:能否实现一个strncpy函数?
二师兄:好的。

[C++] 纯文本查看 复制代码
void strncpy(char *dest, char *src, size_t n)
{
    for (size_t i = 0; i < n; i++)
    {
        *(dest + i) = *(src + i);
    }
}
面试官:额。。如果strlen(src) < n会发生什么?
二师兄:嗯。。那要做个判断。。

[C++] 纯文本查看 复制代码
void strncpy(char *dest, char *src, size_t n)
{
    size_t len = strlen(src) > n ? n : strlen(src);
    for (size_t i = 0; i < len; i++)
    {
        *(dest + i) = *(src + i);
    }
}
面试官:如果strlen(dest) < n呢?
二师兄:因为n是程序员传入进来的,且无法知晓dest的长度,所以这个n要程序员保证它的正确性。
面试官:有没有更简洁的写法?比如利用指针的自增?
二师兄:让我想想。。

[C++] 纯文本查看 复制代码
void strncpy(char *dest, char *src, size_t n)
{
    while(n-- && (*dest++ = *src++));
}
面试官:如果用户传入的src是字符串常量,会发生什么?
二师兄:额。。。让我想想。。明白了,要在src前加上const修饰符:

[C] 纯文本查看 复制代码
void strncpy(char *dest, const char *src, size_t n)
{
    while(n-- && (*dest++ = *src++));
}
面试官:有一些操作需要strcpy嵌套strcpy,如果要实现这个功能,需要做哪些修改?
二师兄:你说的是strncpy(strncpy(...)...)这种操作吗?
面试官:是的。
二师兄:那么需要返回dest地址:

[C++] 纯文本查看 复制代码
char *strncpy(char *dest, const char *src, size_t n)
{
    char *ret = dest;
    while (n-- && (*dest++ = *src++));
    return ret;
}
面试官:如果src和dest的内存地址有重叠,会发生什么?
二师兄:这要分为两种情况,第一种情况:dest < src < dest+n:


二师兄:此时并不需要特殊的处理,拷贝完成后,整个字符串是这样的:


二师兄:虽然src被覆写了,但是dest的内容是正确的。
二师兄:第二种情况,src < dest <src+n;


二师兄:如果直接拷贝,结果会变成这样:


二师兄:此时dest的内容是错误的。所以我们需要对这种情况做特殊处理:

[C] 纯文本查看 复制代码
char *strncpy(char *dest, const char *src, size_t n)
{
    char *ret = dest;
    size_t len = strlen(src) > n ? n :strlen(src);
    if(src < dest && dest < src + len)  //需要从尾部开始拷贝
    {
        const char* s = src + len - 1;
        char* d = dest + len - 1;
        while(len --) *d-- = *s--;
        return ret;
    }
    while (n-- && (*dest++ = *src++));
    return ret;
}
面试官:嗯。有没有什么办法对以上的代码做一些性能上的优化?
二师兄:可以使用SIMD(Single Instruction Multiple Data)指令对strncpy函数做一些优化。*dest++ = *src++每次只能复制一个字节的内容,而SIMD每次可以复制超过一个字节的内容,当数据量大的时候,效率会有明显的提升。
面试官:写过SIMD相关的代码吗?
二师兄:只是听说过,没有用过。
面试官:好的,今天就到这里,请回去等通知吧。

什么是SIMD?SIMD真的能够提升效率吗?
SIMD是一种常见的并行计算技术,一条指令可以同时处理多个数据,所以它可以减少指令的数量,从而提高处理速度。
在X86_64架构下,SIMD的指令集主要包括MMX、SSE、AVX。
下面代码演示如果使用SIMD技术加速大容量字符串的拷贝:
[C++] 纯文本查看 复制代码
#include <emmintrin.h>
void strncpy_simd(char *dest, const char *src, size_t n)
{
    size_t len = strlen(src) > n ? n : strlen(src);
    __m128i *d = (__m128i *)dest;
    const __m128i *s = (const __m128i *)src;
    while (len >= sizeof(__m128i))
    {
        _mm_storeu_si128(d++, _mm_loadu_si128(s++));
        len -= sizeof(__m128i);
    }
    char *dc = (char *)d;
    const char *sc = (const char *)s;

    while (len--)
    {
        *dc++ = *sc++;
    }
}
今天的面试到这里就结束了,感谢大家的耐心~


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-1005679-1-1.html 上篇帖子: C++面试八股文:什么是空指针/野指针/悬垂指针? 下篇帖子: C++面试八股文:如何避免死锁?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表