C言語におけるsizeofとstrlenの違い


この記事は以下のとおりです.http://www.2cto.com/kf/201109/105100.html
1.文字列の形式で現れた場合、コンパイラはその文字列に自動的に0を終端として追加し、コードに「abc」と書くと、コンパイラは「abc0」を格納します.
2.文字ポインタの初期値として文字列の直接量  "helloは文字列の直接量で、コンパイラはそれをconst char*として処理し、それに関連するメモリ空間はメモリの読み取り専用部分にあり、つまりコンパイラが等価文字列の直接量を指す参照を再利用してメモリの使用を最適化することを可能にする.  で文字列の直接量を500回使用し、コンパイラはメモリにインスタンスを作成しただけです.例えば、char*ptr=“hello”;const char*ptr=「hello」に等しい.文字列直接量「hello」は読み取り専用メモリに関連付けられており、修正しようとするとptr[1]=「a」などのエラーが発生する.間違いを引き起こすのです.3.スタックベースの文字配列の初期値として文字列の直接量    スタックベースの変数は、他の場所に格納されているメモリを参照することはできません.コンパイラは、スタックベースの配列メモリに文字列の直接量をコピーします.    たとえば、char stackArray[]="hello";    stackArray[1]=‘a’;確かです.4.文字配列と文字ポインタ    文字配列の形式は次のとおりです.文字の直接量はスタックにコピーされます.          char str[]   = "abc";            //実際のデータストレージ:a b c0、すなわち端子0が追加された          char str[3] = {'a','b','c'};    //実際のデータストレージ:a b c、最後に終端を追加していません          char str[10] = {'a','b','c'};  //実際のデータストレージ:a b c000000000   文字ポインタの形式は次のとおりです.          char *str = “abc”;              //実際のデータ記憶:a b c0、すなわち、終端子05が追加された.タイプの決定    1).配列の種類は,その配列に格納されている要素の種類と配列そのものの大きさによって決まる.         char s 1[3]とchar s 2[4]のように、s 1のタイプはchar[3]、s 2のタイプはchar[4]であり、つまりs 1とs 2は文字配列であるにもかかわらず、両者のタイプは異なる.
    2).文字列定数のタイプは,対応する文字定数配列のタイプとして理解できる.  「abcdef」のようなタイプはconst char[7]と見なすことができ、すなわち実際のデータは「abcdef0」として格納される.
    3).関数パラメータリストの配列タイプで書かれた形式パラメータを,コンパイラは通常のポインタタイプとして解釈する.         void func(char sa[100]、int ia[20]、char*p)の場合、saのタイプはchar*、iaのタイプはint*、pのタイプはchar*である.sizeofとstrlen:1.sizeofオペレータの結果タイプはsize_tは、ヘッダファイルのtypedefがunsigned intタイプである.このタイプは、確立された最大オブジェクトを実装するバイトサイズを収容できることを保証します.2.sizeofは演算子、strlenは関数です.3.sizeofはタイプでパラメータを作ることができ、strlenはchar*でしかパラメータを作ることができず、'0'で終わる必要があります.4.配列をsizeofとするパラメータは劣化せず、strlenに渡すとポインタに劣化します.5.ほとんどのコンパイラはコンパイル時にsizeofを計算し、タイプまたは変数の長さである.これがsizeof(x)が配列次元数を定義するために使用できる理由である.    char str[20]="0123456789";//strはコンパイル期間サイズが固定された配列である     int a=strlen(str);//  a=10;//strlen()は実行時に決定され、実際の長さが計算されます.     int b=sizeof(str);//  b=20;//sizeof()はコンパイル期間中にstrのタイプがint[20]であり、メモリを占有するサイズが計算される6.strlenの結果は実行時に計算され、文字列の実際の長さを計算するために使用され、タイプがメモリを占有するサイズではない.
7.sizeofの後、タイプであれば括弧を付けなければならないが、変数名であれば括弧を付けなくてもよい.これはsizeofがオペレータで関数ではないからです.    char c;    sizeof c; //変数名は括弧を付けなくてもよい8.構造タイプや変数に適用されるとsizeofは実際のサイズを返します.    静的空間配列が適用されるとsizeofはすべての配列のサイズを返す.    sizeofオペレータは、動的に割り当てられた配列または外部の配列のサイズsizeof、strlen計算文字配列、文字ポインタ空間を返すことができません.
char str[] = "abc";        : a b c \0,           \0     char[4] VS: sizeof(str)=4 strlen(str) = 3 GCC: sizeof(str)=4 strlen(str) = 3 char str[] = "abc";        : a b c \0,           \0     char[4] VS: sizeof(str)=4 strlen(str) = 3 GCC: sizeof(str)=4 strlen(str) = 3 char str[] = {'a','b','c'};        : a b c,                char[3] VS: sizeof(str)=3 strlen(str) = 15 GCC: sizeof(str)=3 strlen(str) = 6 char str[3] = {'a','b','c'};        : a b c,                char[3] VS: sizeof(str)=3 strlen(str) = 15 GCC: sizeof(str)=3 strlen(str) = 6 char str[5] = {'a','b','c','d','e'};        : a b c d e ,                char[5] VS: sizeof(str)=5 strlen(str) = 19 GCC: sizeof(str)=5 strlen(str) = 8 char str[5] = {'a','b','c','d'};

実際のデータストア:a b c d0(デフォルトの塗りつぶし文字0) そのタイプはchar[5]   VS: sizeof(str)=5     strlen(str) = 4GCC: sizeof(str)=5     strlen(str) = 4char *pstr = "abcde"; 実際のデータ格納:a b c d e0 pstrのタイプはchar* sizeof(pstr)=4(ポインタのデータ格納空間、4バイト)、strlen(pstr)=5まとめ:1).sizeofの結果はタイプの大きさであり、タイプを区別した後、sizeofの結果も命であり、sizeofの結果はコンパイル期間に決定され、計算された占有メモリの大きさである.     srelenの結果は実行中に決定され、計算されるのは実際の長さであり、strlenはchar*のみをパラメータとし、0を終端とすることができ、以上の例では赤色部分のstrlen計算は誤りであり、     strのデータストレージには0文字が1つもないので、strlenの結果は少し異常に見えます.2).sizeofを計算する際に注意:     char str[] = "abc";  タイプはchar[4]、   sizeof(str)=4*sizeof(char)=4.3).sizeof(express)は、コンパイル中にコンパイルされず、代替タイプである.     例えば、int a=1;sizeof(a=2);     このときのexpressはa=2であり、コンパイル中にsizeof(int)に置き換えられるため、実行後もaは1.4に等しい.関数に対してsizeofを用いると、コンパイル段階で関数の戻り値のタイプに置き換えられる     例:int f(){return 0;}  sizeof(f());の結果は4.             void f(){}            sizeof(f());コンパイル中にエラーが発生し、置換後のsizoeof(void)コンパイルが通過できない.