質問1:
ソースコード 1 とソースコード 2 の結果に違いがあるのはなぜですか?
ソースコード 1:
#include <stdio.h>
#include <string.h>
int main()
{
char c[2]="Hi";
printf("%d", strlen(c)); //returns 3 (not 2!?)
getchar();
}
ソースコード 2:
#include <stdio.h>
#include <string.h>
int main()
{
char c[3]="Hi";
printf("%d", strlen(c)); //returns 2 (not 3!?)
getchar();
}
answer : 最初のケースでc[]
は、「こんにちは」しか保持していないためです。strlen は最後にゼロを探し、背後にあるものに応じてc[]
遅かれ早かれゼロを見つけるか、クラッシュします。c[]
配列の背後にあるメモリに何があるかを正確に知らなければ、何とも言えません。
質問2:
文字列変数は char 配列とどう違うのですか? \0 があれば格納できる最小の必要なインデックス番号でそれらを宣言する方法 (以下のコードを読んでください)?
char name[index] = "Mick"; //should index be 4 or 5?
char name[index] = {'M', 'i', 'c', 'k'}; //should index be 4 or 5?
答え
本当にあなたが何をしたいかによります。実際にコンテンツを文字列として使用する場合は、おそらく 5 です。しかし、「Mick」を 4 文字の配列に格納できないということは何もありません。strlen を使用してその長さを調べることはできません。なぜなら、strlen は 5 まで続き、おそらく (はるかに) さらに長さを見つけるためです。 、次のいくつかのメモリ位置にゼロがない場合、最終的に読み取る有効なメモリ アドレスがなくなるため、クラッシュにつながる可能性があります。
#define name "Mick" //what is the size? Is there a \0?
どこかで名前を使用するまで、これにはまったくサイズがありません。#defines は、コンパイラーが認識するものの一部ではありません。プリプロセッサーは、どこでも使用すると置き換えname
られます。うまくいけば、それはコンパイラーが理解できる場所にあります。そして、前の回答と同じルールが適用されます-文字の配列をどのように使用するかによって異なります。、、およびその他のほぼすべての関数を正しく操作するには、最後にゼロが必要です。"Mick"
name
strlen
strpy
str...
質問 3:
終端の null は文字列のみに続きますが、char 配列には続きませんか? 文字列 "Hi" の実際の値は [H][i][\0] で、文字配列 "Hi" の実際の値は [H][i] ですか?
そうですね。"Hi"
それはすべて、文字列リテラル (「二重引用符で囲まれたもの」の技術的な名前) をどのように使用するかに依存します。コンパイラが「許可」されている場合は、末尾にゼロが追加されます。しかし、配列を特定のサイズに初期化すると、そこにバイトが詰め込まれます。ゼロの余地がない場合、それはあなたの問題であり、コンパイラの問題ではありません。
質問 4:
c[2] が "Hi" の後に \0 を格納しようとしているとします (これがどのように行われるかわかりません。おそらく gets(c) を使用しますか?)。では、\0 はどこに保存されているのでしょうか? c[2] の後の「どこかに」格納されて [H][i]\0 になりますか、それとも c[2] に \0 が追加されて [H][i][\0 である c[3] になりますか]?
c[2] では、「H」、「i」を超えて、何が格納されているかわかりません [技術的には、それは「地球の終わり」である可能性があります。読み取り - その場合strlen
、strlen は地球の果てを超えて読み取るため、プログラムがクラッシュします].しかし、if はゼロ、1、文字 'a'、数字 42、またはその他の 8 ビットである可能性もあります[1] 値。
文字列/文字配列の後に \0 が続くことがあり、if (c1==c2) で 2 つの変数を比較すると、FALSE (0) が返される可能性が高いため、問題が発生することがあります。
c1 と c2 が char 配列の場合、c1 と c2 が同じアドレスを持つことは決してないため、これは常に false になります。C で配列をそのように使用すると、「文字列の最初の要素のメモリ内のアドレス」になります。配列"。したがって、c1 と c2 の内容が何であれ、それらのアドレスが同じになることはありません [これらは 2 つの異なる変数であり、2 つの変数がメモリ内で同じ場所を持つことはできないためです。これは、駐車スペースに 2 台の車を駐車しようとするようなものです。 1 台の車に十分な大きさ - いいえ、どちらの車も押しつぶすことは、私たちの思考実験では許可されていません]。
[1] Char は 8 ビットであることが保証されていません。しかし、今のところそれを無視しましょう。