したがって、C ++で
char
と入力します。
問題の主な原因は次のとおりです。
- 8ビット量の特殊な整数型が言語にないこと。 このため、charはバイトの役割を果たす必要があります。
- 言語内の2つのまったく異なるタイプの文字列
std::string
(「C ++文字列」)およびconst char*
(互換性のためにサポートされる必要があるC文字列)の存在。
最初の項目の詳細。 「ネイティブ型」
byte
がないため、
char
型を使用して構築されます。 標準では、
char
、
signed char
および
unsigned char
タイプが3つの異なるタイプであることを明確に明確にしています。 他の整数型にはこのプロパティがありません。たとえば、
int
と
signed int
は同じ定義です。 ここでの追加の熊手は、char型自体が署名されているか署名されていないという事実です。これはプラットフォーム(大まかに言って、コンパイラとそのキーのセット)に依存します。 しかし同時に、とにかく、コンパイラーはそれらをすべて互いに区別する義務があります。
したがって、そのような定義:
void foo(char c); void foo(signed char c); void foo(unsigned char c);
3つの異なる機能を発表します。 これらのタイプのさまざまなプロパティの「混合」が発生する問題は、たとえば次のコードで示すことができます。
#include <iostream> #include <stdint.h> int main() { uint8_t b = 42; std::cout << b << std::endl; // *, 42. }
要約:特定の状況での「バイト」整数型は、「シンボリック」な本質を明白でない結果で明示できます。
2番目のポイントに進みましょう。 Cでは、文字列を操作するための特別な型はありません。 慣例により、
char*
(または
const char*
)ポインターがある場合、これはおそらく文字列であり、適切な関数に渡すことができると考えられています。 プレーンCでは、たとえば次のような驚くべきことが可能です。
int main(void) { char* ptr = "hello"; // C, ptr[1] = 'q'; // "abcd"[1] = '2'; // - , - read-only, return 0; }
良いニュースは、C ++ではこの「機能」が転送されなかったことです。
しかし、残りはどこにも行っていません。 たとえば、文字列リテラルはそれ自体の内部でヌル文字を許可し(たとえば、
"abc\0\123"
)、それらと連携するように設計された関数(
strlen
など)はそのような文字列をサポートしません。 つまり、「すべての行はゼロで終わる非ゼロ文字のシーケンスである」という決定により、すべての行が「指定された長さを取得する」などの複雑なO(n)文字列。」
さらに、コンパイラはすべての文字列リテラルに
'\0'
を自動的に追加するため、次のような結果になります。
char str1[] = "1234"; // 5 , 4 char str2[4] = "1234"; // , char str3[4] = {'1', '2', '3', '4'}; // ...
すべてが順調に進んでいるようです。 ただし、最後の行には隠しレーキが含まれています。通常の
char*
ように見えます。つまり、
puts
、
strlen
などに渡すことができます。 未定義の動作を取得します。
要約すると、可能な場合は、C ++プログラムで「古い」Cスタイルの文字列を使用しないでください。