web-dev-qa-db-ja.com

C ++-文字*対文字列*

文字列変数array of charsを指すポインターがある場合、次のように入力すると違いがあります。

char *name = "name";

そして、

string name = "name";
16
Simplicity

はい、違いがあります。主に文字列を変更できますが、最初のバージョンを変更することはできませんできません –ただし、C++コンパイラは、これが禁止されていることを警告しません。

したがって、常に2番目のバージョンを使用してください。

If何らかの理由でcharポインタを使用する必要がある場合は、constにしてください:

char const* str = "name";

ここで、strの内容を変更しようとすると、コンパイラーはこれを(正しく)禁止します。また、コンパイラの警告レベルを一段上げる必要があります。そうすると、最初のコード(char* str = "name")は合法ですが非推奨です。

29
Konrad Rudolph

はい、2つ目は有効なC++ではありません! (コンパイルされません)。

stringはさまざまな方法で作成できますが、1つの方法は次のとおりです。

string name = "name";

ポインタとして宣言する必要がないため、*は必要ないことに注意してください。

9

まず第一に、あなたはおそらく変更したいでしょう

string *name = "name";

読む

string name = "name";

string*char*は根本的に異なる型であるため、最初のバージョンはコンパイルされません。

stringchar*の違いは、char*がシーケンスへの単なるポインタであることです。文字列を操作するこのアプローチは、Cプログラミング言語に基づいており、C++で文字列をエンコードするネイティブな方法です。 C文字列を扱うには少しトリッキーです-それらが適切にスペースを割り当てるようにし、それらが占有するバッファーの終わりから外れないようにし、それらを可変メモリに入れてセグメンテーション違反などを回避する必要があります。主な関数それらを操作するための<cstring>にあります。ほとんどのC++プログラマーは、Cスタイルの文字列を使用することを推奨していません。これらは本質的に操作が難しいためですが、下位互換性と、低レベルAPIが構築できる「最低の共通点」の両方としてサポートされています。

C++スタイルのstringは、文字列をカプセル化するオブジェクトです。メモリ管理の詳細はユーザーには表示されません(ただし、すべてのメモリが連続していることは保証できます)。演算子のオーバーロードを使用して、連結などのいくつかの一般的な操作を使いやすくし、検索、置換、部分文字列などの高レベルの操作を実行するように設計されたいくつかのメンバー関数もサポートします。また、CでもSTLアルゴリズムと相互運用するように設計されていますスタイルの文字列でもこれを行うことができます。

要するに、C++プログラマーとしては、おそらくstringタイプを使用するほうがよいでしょう。安全で、少し使いやすいです。 Cスタイルの文字列については、プログラミングのキャリアで確かに出会うので、知っておくとよいでしょう。ただし、やむを得ない理由がない限り、stringも使用できるプログラムでは使用しないことをお勧めします。そう。

9
templatetypedef

char* name = "name"は無効にする必要がありますが、ほとんどのシステムでコンパイルして、constが存在しなかった昔の時代との下位互換性を確保し、コンパイルしないと大量のレガシーコードを破壊します。ただし、通常は警告が表示されます。

危険なのは、書き込み可能なデータ(C++のルールに従って書き込み可能)へのポインターを取得することですが、実際にデータを書き込もうとすると、未定義の動作が呼び出され、言語ルールは、それを可能な限り保護しようとします。可能。

正しい構成は

const char * name = "name";

C++でさえ、上記に問題はありません。文字列を使用する方が常に正しいとは限りません。

2番目のステートメントは本当に

std::string name = "name";

stringは、標準ライブラリで定義されたクラス(実際にはbasic_string<char,char_traits<char>,allocator<char>のtypedef)であり、名前空間std(basic_string、char_traits、アロケータと同様)で定義されています。

Charの配列を使用するよりもstringを使用する方がはるかに望ましいさまざまなシナリオがあります。たとえば、当面のケースでは、それを変更できます。そう

name[0] = 'N';

(最初の文字を大文字に変換)は文字列で有効であり、char *(未定義の動作)またはconst char *(コンパイルされません)では無効です。 char name[] = "name";がある場合は、文字列を変更できます。

ただし、文字列に文字を追加する場合は、std :: stringコンストラクトがそれをきれいに実行できる唯一のものです。古いC APIではstrcat()を使用する必要がありますが、それを行うのに十分なメモリを割り当てていない場合は無効になります。

std :: stringはメモリを管理するため、malloc()などを呼び出す必要はありません。実際には、3番目のテンプレートパラメータであるアロケータがその下のメモリを管理します。basic_stringは必要なメモリ量を要求しますが、実際のメモリから切り離されていますメモリ割り当て手法を使用しているため、std :: stringを使用してもメモリプールなどを効率的に使用できます。

さらに、basic_stringは実際にはchar_traitsを介して行われる文字列操作の多くを実行しません。 (これにより、最適化された下にある専門のC関数を使用できます)。

したがって、std :: stringは、(リテラルだけでなく)実行時に構築および渡される動的文字列を処理するときに、文字列を管理するための最良の方法です。

String *(文字列へのポインタ)を使用することはほとんどありません。これを行うと、他のポインターと同様に、オブジェクトへのポインターになります。あなたがしたようにそれを割り当てることができないでしょう。

4
CashCow

C++文字列クラスは、char Cのような文字列をカプセル化しています。はるかに便利です(http://www.cplusplus.com/reference/string/string/)。

レガシーの場合、文字列変数からcharポインターを常に「抽出」して、charポインターとして処理できます。

    char * cstr;
    string str ("Please split this phrase into tokens");
    cstr = new char [str.size()+1];
    strcpy (cstr, str.c_str());    //here str.c_str() generate null terminated char* pointer
    //str.data() is equivalent, but without null on end
1
udjin

はい、char*は文字列である文字の配列へのポインタです。 string *は、std::stringの配列へのポインターです(これはほとんど使用されません)。

string *name = "name"; 

「名前」はconst char*であり、std::string*に変換されることはありません。これにより、コンパイルエラーが発生します。

有効な宣言:

string name = "name";

または

const char* name = "name"; // char* name = "name" is valid, but deprecated
0
Hoàng Long