🐥

【C言語】strcmp関数の自作

2022/10/18に公開
2

きっかけ

strcmpが自作できるよと教えて頂いたので、早速やってみる。

とりあえず関数を自作してみる。

strcmp自作の前に、投げた値を3倍して返す関数を自作してみる。

#include <stdio.h>

int	triple(int value);

int	main(void)
{
	int	return_value;

	return_value = triple(3);
	printf("%d\n", return_value);
	return (0);
}

int	triple(int value)
{
	return (value * 3);
}

strcmpを自作していく。

とりあえず完成形

#include <stdio.h>

int	my_strcmp(const char *x, const char *y)
{
	int	count;

	count = 1;
	while (*x)
	{
		printf("in while(%d) *x: %c\n", count, *x);
		printf("in while(%d) *x: %c\n", count, *y);
		printf("in while(%d) *(const unsigned char*)x: %d\n",
			count, *(const unsigned char*)x);
		printf("in while(%d) *(const unsigned char*)x: %d\n",
			count, *(const unsigned char*)y);
		if (*x != *y)
		{
			break ;
		}
		x++;
		y++;
		count++;
	}
	return (*(const unsigned char *)x - *(const unsigned char *)y);
}

int	main(void)
{
	const char	*x = "abc";
	const char	*y = "abd";
	const int	return_value = my_strcmp(x, y);

	printf("raw x: %s\n", x);
	printf("raw y: %s\n", y);
	printf("return_value: %d\n", return_value);
	return (0);
}

参考にさせて頂いたサイト

コードの考察

まだよく理解できてないところ

  • 変数名の横の*。調べてポインタ型の変数だということはわかったけどまだちゃんと理解し切れてない。
  • while(*x)。Xが0になったら終わるっぽい?だとしてもどのタイミングでXが0になるのだろうか。
    (多分最後の文字に来たとき、もう1つ右には何も無い(or NULL文字?)からその段階で0になるかな?

とりあえず追ってみる

main関数

xにabc、yにabdを代入する。
my_strcmp関数にxとyを投げて、返ってきた値をprintする。

my_strcmp関数

XとYを頭から1文字づつ比較していく。
それを比較した2つの文字が異なる、もしくはxが0になるまでくり返す。
x(の文字コード?)からy(〃)を引いた値を返す。(2つの文字列が最後まで一致した場合は0になる)

まとめ

今回なんやかんやここまで来るのに2時間程度かかりましたが、いろいろなものを調べながら書き進めて行けたので、とても勉強になりました。

参考

https://9cguide.appspot.com/11-01.html
https://9cguide.appspot.com/11-02.html

Discussion

齊藤敦志齊藤敦志

while(*x)。Xが0になったら終わるっぽい?だとしてもどのタイミングでXが0になるのだろうか。

なるというよりも文字列の終端には実際にゼロが入っています。 文字列リテラルの終端にはゼロが入りますし、プログラマが文字列を構築するときも文字列の終端にゼロを入れるという約束を守るという前提で成り立っています。

#include <stdio.h>

int main(void) {
  char foo[]="abcdefg";
  foo[3]='\0'; // d の上にゼロを書き込む
  printf("%s\n", foo); //出力されるのは abc
  // ゼロがあればそこが終端と見なされる
}

ゼロが入っていない文字列を作ってしまったら偶然にゼロにぶち当たるまでデタラメにメモリを読み続けたり、そのままアクセスが許されていないメモリ領域を読もうとして segmentation fault になったりするでしょう。 (言語仕様ではそのような状況を未定義としていますのでどうなるかわかりません。)

くまさんくまさん

なるほど。文字列の終端には0が入っているんですね。
ありがとうございます。