はい、文字列は特別なデータ オブジェクトと操作を含む線形リスト構造です。データ構造で言及される文字列は文字列であり、文字列内の文字には「1 対 1」の論理関係があるため、厳密に言えば、文字列の記憶構造は線形記憶構造です。
このチュートリアルの動作環境: Windows 7 システム、Dell G3 コンピューター。
データ構造で言及される文字列、つまり文字列は、n 個の文字 (n >= 0) から構成される全体です。これらの n 文字は、文字、数字、またはその他の文字で構成できます。
データ構造では、文字列は文字列記憶構造と呼ばれる別の記憶構造に保存する必要があります。
厳密に言えば、文字列内の文字には「1 対 1」の論理関係があるため、文字列の記憶構造も線形記憶構造です。ただし、前に学習した線形ストレージ構造とは異なり、文字列構造は文字型データを格納するためにのみ使用されます。
#特別な文字列
例: a = "BEI"、b = "BEIJING"、c = "BJINGEI"。文字列 a と b の場合、b には連続文字列 a, が含まれているため、a は b の部分文字列、b は a の主文字列であると言えます。また、c と a については、c ですが、また、a のすべての文字が含まれていますが、連続する "BEI" は含まれていないため、文字列 c は a と関係がありません。メイン文字列内のサブ文字列の位置: 文字列 a = "BEI" の場合、文字列 b の最初の文字 'B' の位置は 1 であるため、メイン文字列内のサブ文字列 a の位置b = 「BEIJING」の位置は 1 です。
主文字列内の部分文字列の位置は、配列内の文字の格納位置と異なります。主文字列内の部分文字列の位置は 1 から始まります。 2 つの文字列の等価性の標準: 2 つの文字列の文字列値がまったく同じである場合、2 つの文字列は等しいです。
#文字列の保存には 3 つの保存構造があります#文字列の保存には 3 つの構造があります:
1 固定長シーケンシャル ストレージ;
2 ヒープ割り当てストレージ; 3 ブロック チェーン ストレージ。固定長シーケンシャルストレージ
固定長配列 (静的配列) を使用して文字列を保存します。
例: char a[7] = "abcdfg";この方法で文字列を保存する場合は、文字列の長さを見積もり、事前に十分な保存領域を申請する必要があります。 。ターゲット文字列が配列で要求された長さを超える場合、超過部分は自動的に破棄されます (「切り捨て」と呼ばれます)。 例: char a[3] = "abcdfg";//実際には、配列には「abc」のみが格納され、それ以降は切り捨てられます。ヒープ割り当てストレージ動的配列を使用して文字列を格納します
C 言語では、malloc 関数と Free 関数管理を使用して「ヒープ」と呼ばれる空き記憶領域があります。 , malloc 関数はスペースの申請を担当し、free 関数はスペースの解放を担当します。
例:char * a = (char*)malloc(5*sizeof(char));//创建 a 数组,动态申请5个 char 类型数据的存储空间ヒープ割り当てストレージを使用する利点は、適用されたスペースが十分ではないことが判明した場合に、realloc( ) 関数。
例如:a = (char*)realloc(a, 10*sizeof(char));//前一个参数指申请空间的对象;第二个参数,重新申请空间的大小malloc 関数の使用に適用されたストレージ領域は自動的に解放されないため、プログラマは free() 関数を呼び出して手動で解放する必要があります。手動で解放しない場合は、プログラムの実行が完全に完了したときにオペレーティング システムによってリサイクルされます。
例如:free(a);//释放动态数组a申请的空间完全な例を挙げると、接続文字列「abc」と「defg」は「abcdefg」になります;
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char * a1=NULL; char * a2=NULL; a1=(char*)malloc(3*sizeof(char)); strcpy(a1, "abc");//将字符串“abc”复制给a1 a2=(char*)malloc(3*sizeof(char)); strcpy(a2, "defg"); int lengthA1=strlen(a1); int lengthA2=strlen(a2); if (lengthA1<lengthA1+lengthA2) { a1=(char*)realloc(a1, (lengthA1+lengthA2)*sizeof(char)); } int i; for (i=lengthA1; i<lengthA1+lengthA2; i++) { a1[i]=a2[i-lengthA1]; } printf("%s",a1); free(a1); free(a2); return 0; }
注: プログラムでは、 a1とa2に値を代入する際にはstrcpyのコピー関数を使用しました。ここでは直接使用できません: a1 = "abc".
これを実行すると、プログラムはコンパイル時にエラーが発生し、malloc のない領域は解放できないことが通知されます。 理由は次のとおりです。 strcpy 関数は文字列を適用された記憶領域にコピーしますが、直接代入は文字列が別のメモリ領域 (それ自体は定数であり、定数領域に配置されます) に格納されることを意味します。 ポインタ a1 と a2 のポインティングが変更されており、つまり、以前に動的に申請された記憶域が、使用される前に失われています。ブロック チェーン ストレージ
ブロック チェーン ストレージは、実際にはリンク リストのストレージ構造を借用して文字列を保存します。通常の状況では、単一のリンク リストを使用するだけで十分であり、ヘッド ノードを追加する必要はありません。
リンク リストを作成する場合、各ノードは 1 文字または複数の文字を保存できます。链表中最后一个结点的数据域不一定全被串值占满,通常会补上 “#” 或者其他特殊的字符和字符串中的字符区分开。
每个结点设置字符数量的多少和存储的串的长度、可以占用的存储空间以及程序实现的功能相关。
如果串包含数据量很大,但是可用的存储空间有限,那么就需要提高空间利用率,相应地减少结点数量(因为多一个节点,就多申请一个指针域的空间)。
而如果程序中需要大量地插入或者删除数据,如果每个节点包含的字符过多,操作字符就会变得很麻烦,为实现功能增加了障碍。
总结
在平时编写程序,经常会用到例如:char *a = ”abcd”;这种方式表示字符串,和上面三种存储方式最主要的区别是:这种方式用于表示常量字符串,只能使用,不能对字符串内容做修改(否则程序运行出错);而以上三种方式都可以对字符串进行删改的操作。
例如:
#include <stdio.h> int main() { char* a="abcd"; a[1]='b'; return 0; }
程序编译可以通过,运行失败,改成下面堆分配存储的方式就对了:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char * a=(char*)malloc(4*sizeof(char)); strcpy(a, "abcd"); a[1]='e'; printf("%s",a); return 0; }
三种存储表示方式中,最常用的是堆分配存储,因为它在定长存储的基础上通过使用动态数组,避免了在操作串时可能因为申请存储空间的不足而丢失字符数据;和块链存储方式相比,结构相对简单,更容易操作。
更多计算机编程相关知识,请访问:编程视频!!
以上が文字列は特別なデータ オブジェクトと操作を含む線形リストですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。