目次
5. strlen関数のシミュレーション実装:(3つの方法)
(1)、strlen: 文字列の長さを求める
1. 関数の役割:
文字列の長さを調べるために使用されます。
2. 関数宣言:
size_t strlen ( const char * str );
説明する:
(1).関数のパラメータはchar* ポインタ str で、取得する文字列の先頭アドレスを受け取るために使用されますが、const の機能はポインタ str の変更を防ぐことです。
(2).関数の戻り値はstr が指す文字列の長さで、'\0' に達すると統計は終了します。戻り値の型は size_t (符号なし整数) です。
3. 機能に関するメモ:
(1). 文字列では終了マークとして '\0' が使用されており、strlen 関数は文字列内の '\0' の前に現れる文字数を返すことがわかります。
(2). パラメータ str が指す文字列は '\0' で終わる必要があり、そうでない場合は予期しない結果が発生します。
(3). この関数はヘッダー ファイル <string.h>に含まれています。
4. 関数の使用例:
以下に示すように:
最初の 3 つは分かりやすいですが、配列のサイズは 6 バイトですが、最初の 3 つは初期化されると最後に「\0」が自動的に追加されるため、「\0」を格納するために 1 バイトのスペースが必要になります。したがって、文字列の長さは 5 になります。4 番目の初期化メソッドでは、文字列の末尾に「\0」が自動的に追加されないため、strlen は「\0」に到達するまでカウントを続け、ランダムな値を計算します。
5. strlen関数のシミュレーション実装:(3つの方法)
(1).カウンター方法
ソースコードは次のとおりです。
//计数器模拟实现strlen
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
assert(str);
size_t count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
size_t sz = my_strlen("abcdef");
printf("该字符串长度为:%zu\n", sz);
return 0;
}
説明する:
①:シミュレーション実装なのでパラメータや戻り値の型は同じである必要があります。
②: strlen 関数は統計原理により「\0」に遭遇すると停止するので、変数(カウンタ)を作成して while ループを利用するだけで済みます ポインタ str の指す値が等しくない場合'\0' の場合、カウンターは +1 になり、str が指す値が '\0' に等しくなるまで、ポインター +1 によって次の文字が決定され、ループが終了します。最後にカウンターの値を返します。
③: Assert 関数を知らない友達もいるかもしれませんが、実際にはこの関数はポインタ str が空かどうかを確認するためにのみ使用されます。興味のある友達は自分で勉強して、興味のない人は無視してください。
(2).ポインタ - ポインタ
ソースコードは次のとおりです。
//指针-指针实现strlen
#include<assert.h>
#include<stdio.h>
size_t my_strlen(const char* str)
{
assert(str);
const char* end = str;
while (*end != '\0')
{
end++;
}
return end - str;
}
int main()
{
size_t sz = my_strlen("abcdef");
printf("该字符串长度为:%zu\n", sz);
return 0;
}
説明する:
①: まず第一に、ポインタについて理解する必要があります。ポインタは何を取得するのでしょうか?
答え: ポインター - ポインターは 2 つのポインター間の要素の数を取得します。
②: 上記に基づいて、str と同じ型のポインタ end を作成し、str を end に代入し、上記のように while ループを通じて end が指す値を文字列内の '\0' にポイントすることができます。この目的は ++ 操作によって達成できます。
③: 最後に、「\0」から先頭アドレスまでの要素数である end - str を返します。
(3) 再帰的手法
ソースコードは次のとおりです。
//递归实现strlen
size_t my_strlen(const char* str)
{
if (*str != '\0')
{
str++;
return 1 + my_strlen(str);
}
return 0;
}
int main()
{
size_t sz = my_strlen("abcdef");
printf("该字符串长度为:%zu\n", sz);
return 0;
}
説明する:
再帰は抽象的すぎるため、以下に示すように、それを理解するために図を描きます。
(2)、strcpy: 文字列のコピー
1. 関数宣言:
char * strcpy ( char * destination, const char * source );
説明する:
①: 関数には2 つの仮パラメータがあります。
最初の仮パラメータは char* ポインタで、これはターゲット空間です。
2 番目の仮パラメータ const char* ポインタはソース文字列です。
ソース ポインタが指すソース文字列をターゲット空間にコピーするだけです。
②:戻り値は(関数の連鎖アクセスに便利)。
③: この関数はヘッダーファイル <string.h>に含まれています。
2. 関数の役割:
参照関数の宣言は、仮パラメータのソースが指すソース文字列を、「\0」を含む仮パラメータの宛先が指すターゲット空間にコピーすることです。
3. 機能に関するメモ:
①: ソース文字列は「\0」で終わる必要があります。
②: ソース文字列の「\0」もターゲット空間にコピーされます。
③: ターゲット領域は、ソース文字列を確実に格納できるのに十分な大きさでなければなりません。
④: 対象空間は変数である必要があるため、const による修飾は行われません。
4. 関数の使用例:
1.通常の使用:
ソースコードは次のとおりです。
#include<string.h> #include<stdio.h> int main() { char arr1[] = { 'a','b','c','\0' }; char arr[10] = " "; strcpy(arr, arr1); printf("%s\n", arr); return 0; }
操作結果:
2. ターゲット領域が十分に大きくない場合:
3. ターゲット空間が不変の場合:
5. strcpy 関数のシミュレーション実装:
ソースコード:
//模拟实现strcpy #include<stdio.h> #include<assert.h> char* my_strcpy(char* dest, const char* sour) { assert(dest && sour); char* tmp = dest; while (*dest++ = *sour++) { ; } return tmp; } int main() { char arr[] = "abcdef"; char dest[10] =" "; my_strcpy(dest,arr); printf("%s\n", dest); return 0; }
説明する:
①:シミュレーション実装なので戻り値の型とパラメータは同じである必要があります。
②: アイデア: '\0' で終わるまで 1 文字ずつコピーします。
③: 対象空間の開始アドレスを返す必要があるため、まず対象空間の開始アドレスを保存するためのポインタ変数 tmp を作成します。
④: 次に、while ループを使用して 1 文字ずつコピーし、sour が指す値を dest が指す空間に代入し、sour が指す値が '\0' に等しいかどうかを判断します。そうでない場合は、sour とdest +1 の両方で、次の文字をコピーします。それが '\0' に等しい場合は、'\0' をコピーしてループが終了するため、'\0' の ASCII 値は 0 になります。
⑤:最後に対象空間の先頭アドレスtmpを返します。
(3)、strcat: 文字列の追加
1. 関数宣言:
char * strcat ( char * destination, const char * source );
説明する:
①: 関数には2 つの仮引数があります。
最初の仮引数は char* ポインタで、これは追加される文字列 (ターゲット空間) であるため、const で変更する必要はありません。2 番目の仮パラメータは、ソース文字列である const char* ポインタです。ソース文字列は変更できないため、const で変更されます。
この関数は、source が指すソース文字列を、destination が指す追加される文字列の末尾に追加します。
②:関数の戻り値は付加する文字列の先頭アドレスになります。
③: この関数はヘッダーファイル <string.h>に含まれています。
2. 関数の役割:
関数宣言を参照します。つまり、source が指すソース文字列を、destination が指す追加される文字列の末尾に追加します。
3: 機能に関する注意事項:
1. ソース文字列sourceは「\0」で終わる必要があります。
2. ターゲット領域は、ソース文字列を収容できる十分な大きさでなければなりません。
3. ターゲット空間は変更可能である必要があります。
4. 自分自身に余計なものを加えないようにしてください。
4: 関数の使用例:
ソースコードは次のとおりです。
#include<string.h> int main() { char arr[] = "world"; char dest[20] = "hello "; strcat(dest, arr); printf("%s\n", dest); return 0; }
操作結果:
5: strcat 関数のシミュレーション実装:
ソースコード:
//模拟实现strcat #include<assert.h> #include<stdio.h> char* my_strcat(char* destination, const char* source) { assert(destination && source); //存目标空间首地址 char* tmp = destination; //找到目标空间'\0'的位置; while (*destination) { destination++; } //从目标空间'\0'位置开始,将源字符串的字符一个个的拷贝进来,与strcpy类似 while (*destination++ = *source++) { ; } return tmp; } int main() { char arr[] = "world"; char dest[20] = "hello "; my_strcat(dest, arr); printf("%s\n", dest); return 0; }
説明する:
①:シミュレーション実装なので戻り値やパラメータは同じである必要があります。
②: アイデア: まず、ターゲット空間の '\0' 位置を見つけ、この位置から開始して、コピーがソース文字列の '\0' で終了するまで、ソース文字列の内容を 1 文字ずつコピーします。
③:戻り値が対象空間の先頭アドレスとなるため、まず先頭アドレスを変数tmpに保存します。
④: 次に、while ループを使用して、ポインターの宛先をターゲット空間の '\0' 位置に指定します。
⑤:この位置から、strcpy関数を使用して実装方法をシミュレートし、ソース文字列の'\0'にコピーした後、ループが終了するまでソース文字列の内容を1文字ずつコピーします。
⑥:最後に対象空間の先頭アドレスtmpを返します。
⑦: このシミュレーション実装には、それ自体に追加できないという欠点があります。
(4)、strcmp: 文字列比較
1. 関数宣言:
int strcmp ( const char * str1, const char * str2 );
説明する:
1. この関数には2 つのパラメータがあります。パラメータの型は同じです。比較のみが必要で、元の文字列の内容は変更できないため、const で変更されます。
2.この関数の戻り値の型は int であり、戻り値は以下の規格に準拠します。
3. この関数はヘッダー ファイル <string.h>に含まれています。
2. 関数の役割:
この関数は 2 つの文字列を比較するために使用されます。
比較方法:
2つの文字列の対応する位置にある文字を取り出し、ASCIIコード値を1つずつ比較し、最初の文字が同じ、つまりASCIIコード値が同じ場合は、その文字列のASCIIコード値を比較します。 2番目の文字。
比較ルール:
3. 関数の使用例:
4. strcmp 関数のシミュレーション実装:
ソースコード:
//模拟实现strcmp #include<stdio.h> #include<assert.h> int my_strcmp(const char* str1, const char* str2) { assert(str1 && str2); while (*str1 == *str2) { if (*str1 == '\0' && *str2 == '\0') return 0; str1++; str2++; } return *str1 - *str2; } int main() { printf("%d\n", my_strcmp("abc", "azc")); return 0; }
説明する:
①:シミュレーション実装なので戻り値やパラメータは同じである必要があります。
②: まず、while ループを使用して 2 つの文字列が等しいかどうかを 1 文字ずつ判定し、両方が等しい場合は「\0」で 0 を返し、特定の文字が等しくない場合はループを終了します。を返し、*str1 - *str2 を返します。ASCII コード値に基づいて比較するため、*str1 が *str2 より大きい場合、2 つの減算により 0 より大きい数値が返されます。*str1 が *str2 より小さい場合、この場合、2 つの減算は 0 未満の数値を返しますが、これは標準に準拠しています。
(5)、strstr: 文字列内の部分文字列を検索します。
1. 関数宣言:
const char * strstr ( const char * str1, const char * str2 );
char * strstr ( char * str1, const char * str2 );
説明する:
1. この関数には2 つのパラメータがあり、メイン文字列 str1 を検索してサブ文字列 str2 があるかどうかを確認します。
2.戻り値:
サブ文字列 str2 がメイン文字列 str1 内に見つからない場合は、NULL (ヌル ポインタ) が返されます。
見つかった場合は、メイン文字列 str1 内で最初に出現した部分文字列 str2 の最初のアドレスが返されます。
2. 関数の役割:
つまり、メイン文字列 str1 内のサブ文字列 str2 を見つけます。
見つからない場合は NULL を返します。
見つかった場合は、メイン文字列 str1 内で最初に出現した部分文字列 str2 の最初のアドレスを返します。
3.使用例:
4. strstr 関数のシミュレーション実装:
//模拟实现strstr
#include<assert.h>
char* my_strstr(char* str1, char* str2)
{
assert(str1 && str2);
char* cp = str1;
char* s1 = cp;
char* s2 = str2;
while (*cp)
{
//开始匹配
s1 = cp;
s2 = str2;
while (*s1 && *s2 && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cp;
}
cp++;
}
return NULL;
}
int main()
{
char arr1[] = "abbbcdef";
char arr2[] = "bbc";
char* ret = my_strstr(arr1, arr2);
if (ret != NULL)
printf("%s\n", ret);
else
printf("找不到\n");
return 0;
}
(6)、strtok: ストリングカット
この機能はほとんど使用されないため、以下の説明のみを記載します。
関数の使用例:
この知識はこれで終わりです。お役に立てば幸いです。