某日二師兄參加XXX科技公司的C++工程師開發崗位第31面:
面試官:
strcpy函式使用過吧?二師兄:用過,
面試官:這個函式有什么作用?
二師兄:主要用做字串復制,將于字符從一個位置復制到另一個位置,
面試官:
strncpy函式也使用過吧,和strcpy有何不同?二師兄:
strncpy多了一個size_t的引數,用于避免緩沖區溢位,面試官:能否實作一個
strncpy函式?二師兄:好的,
void strncpy(char *dest, char *src, size_t n)
{
for (size_t i = 0; i < n; i++)
{
*(dest + i) = *(src + i);
}
}
面試官:額,,如果
strlen(src) < n會發生什么?二師兄:嗯,,那要做個判斷,,
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要程式員保證它的正確性,面試官:有沒有更簡潔的寫法?比如利用指標的自增?
二師兄:讓我想想,,
void strncpy(char *dest, char *src, size_t n)
{
while(n-- && (*dest++ = *src++));
}
面試官:如果用戶傳入的
src是字串常量,會發生什么?二師兄:額,,,讓我想想,,明白了,要在
src前加上const修飾符:
void strncpy(char *dest, const char *src, size_t n)
{
while(n-- && (*dest++ = *src++));
}
面試官:有一些操作需要
strcpy嵌套strcpy,如果要實作這個功能,需要做哪些修改?二師兄:你說的是
strncpy(strncpy(...)...)這種操作嗎?面試官:是的,
二師兄:那么需要回傳
dest地址:
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的內容是錯誤的,所以我們需要對這種情況做特殊處理:
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技術加速大容量字串的拷貝:
#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++;
}
}
今天的面試到這里就結束了,感謝大家的耐心~
關注我,帶你21天“精通”C++!(狗頭)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/556523.html
標籤:其他
下一篇:返回列表
