strcat strcpy 深入研究(解決亂碼等問題)


strcat是將一個字符串鏈接到另外一個字符串上的函數,具體形式如下:

char* strcat(char* dest,const char* src)

函數的具體流程如下:
1.先查找dest字符串的結尾(即'\0')
2.然后從dest字符串的結尾位置(即'\0'所在的位置)開始,復制src中的字符(包括結尾'\0')。產生的結果是dest的結尾'\0'會被覆蓋掉,最后產生一個新的結尾。
3.將dest返回(一般用不到)
注意事項
1.dest必須被初始化,即包含一個'\0'結尾。用malloc分配字符串時,經常發生沒有初始化的錯誤。有時候也會正常執行,是因為分配到的內存中,第一個單元的內容剛好為'\0'。但是不能保證每次都這么好運。所以初始化還是有必要的。
可以這樣進行初始化
char* str=(char*) malloc(sizeof(100));
*str='\0';//注意這里是單引號,以為*str表示str所在地址存儲的一個char
或者
*str=0;
也可以這樣strcpy(str,"");
2.src也必須初始化,包含一個'\0'的結尾,不過這個一般發生錯誤的概率較小,因為很多時候直接使用一個字符串做參數strcat(dest,"hello world.")。
3.dest所指向內存的大小必須 >=strlen(dest)+strlen(src)+1,否則會發生 不可知的錯誤,比如 亂碼。使用之前要先確認dest的空間足夠大再使用strcat函數。
 
glibc中的源碼 strcat.c
char *
strcat (dest, src)
     char *dest;
     const char *src;
{
  char *s1 = dest;
  const char *s2 = src;
  reg_char c;
 
  /* Find the end of the string.  */
  do
    c = *s1++;
  while (c != '\0');
 
  /* Make S1 point before the next character, so we can increment
     it while memory is read (wins on pipelined cpus).  */
  s1 -= 2;
 
  do
    {
      c = *s2++;
      *++s1 = c;
    }
  while (c != '\0');
 
  return dest;
}
 
strcpy是將一個字符串復制到另外一個字符串地址上的函數,函數形式如下:
char* strcpy(char* dest,char* src)
 
函數流程
1.將src中的字符(包括結尾'\0')一個個復制到dest中,dest原來的字符將被覆蓋掉。
2.將dest指針返回
注意事項:
1.dest可以不初始化,比如
char *str=(char*) malloc(sizeof(char)*100);
strcat(str,"hellow world!");
2.利用這一特性,可以用來初始化字符串變量
strcat(str,"");將達到和
*str=0;一樣的效果
 
glibc中strcpy.c的函數實現
char *
strcpy (dest, src)
     char *dest;
     const char *src;
{
  reg_char c;
  char *__unbounded s = (char *__unbounded) CHECK_BOUNDS_LOW (src);
  const ptrdiff_t off = CHECK_BOUNDS_LOW (dest) - s - 1;
  size_t n;
 
  do
    {
      c = *s++;
      s[off] = c;
    }
  while (c != '\0');
 
  n = s - src;
  (void) CHECK_BOUNDS_HIGH (src + n);
  (void) CHECK_BOUNDS_HIGH (dest + n);
 
  return dest;
}
 
有沒有發現這個代碼實現的很tricky,off是(dest的地址-src的地址-1)
c = *s++;
s[off] = c;
相當於
c = *s++;
dest++= c;
不過我感覺這樣的代碼格式不值得推薦,效率上一樣,但是閱讀性更差。讓人很難看懂。下面就扯兩句,代碼寫的讓人看得懂,比少些幾行,提高一點點效率更重要。更何況,很多時候經過編譯器的優化,少些的那幾行不見得更高效。具體的可以看看《重構 改善既有代碼的設計》這本書。先聲明一下,我不是賣書的,和這本書的作者沒有一毛錢關系:-D。
本文由ladd原創,歡迎轉載,但請注明出處:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM