string.c char* safestrcpy(char *s, const char *t, int n)

トップページ
jupiteroak.hatenablog.com


string.c
https://github.com/mit-pdos/xv6-public/blob/master/string.c#L82

char* safestrcpy(char *s, const char *t, int n)
{
  char *os;

  os = s;
  if(n <= 0)
    return os;
  while(--n > 0 && (*s++ = *t++) != 0)
    ;
  *s = 0;
  return os;
}

safestrcpy関数は、先頭アドレスが引数t・サイズが引数nのメモリ領域(読み取り対象となるメモリ領域)から、先頭アドレスが引数s・サイズが引数nのメモリ領域(書き込み対象となるメモリ領域)へ、null終端文字列をコピーします。

引数 char *s,
書き込み対象となるメモリ領域の先頭アドレスです。

引数 const char *t,
読み取り対象となるメモリ領域の先頭アドレスです。

引数 int n
書き込み・読み取り対象となるメモリ領域のサイズ(バイト単位)です。

戻り値 char *os
書き込み対象となるメモリ領域の先頭アドレスです。


処理の内容

サイズnが0以下の場合はリターン

os = s;
if(n <= 0)
  return os;

引数nで指定されたサイズが0以下の場合は、書き込み対象となるメモリ領域の先頭アドレスを戻り値としてリターンします。

文字列データを1バイトずつコピーする

while(--n > 0 && (*s++ = *t++) != 0)
   ;

読み取り対象のメモリ領域から、書き込み対象のメモリ領域へ、文字列データを1バイトずつコピーします。
while文のループは、nが0以下になった場合、*sに値が含まれない場合、*tに値が含まれない場合に、終了します。

ループ1 ループ2 ... ループn-1 ループn ループ n+1
nの評価 n n-1 ... 2 1 0
--nの評価 n-1 n-2 ... 1 0 -1
s++の評価 s(先頭アドレス) s+1 ... s+n-2 s+n-1(終端アドレス) s+n
t++の評価 t(先頭アドレス) t+1 ... t+n-2 t+n-1(終端アドレス) t+n

ヌル終端文字列にする

s = 0;

書き込み対象となるメモリ領域の最後の1バイトをヌル文字にします。

先頭アドレスが引数s・サイズが引数nのメモリ領域(書き込み対象となるメモリ領域)の先頭アドレスを戻り値としてリターン

return os;

書き込み対象となるメモリ領域の先頭アドレスを戻り値としてリターンします。