違いは何ですか
char* name
定数文字列リテラルを指す
const char* name
違いは何ですか
char* name
定数文字列リテラルを指す
const char* name
回答:
char*
ある可変へのポインタ可変文字/文字列。
const char*
ある可変へのポインタ不変の文字/文字列。このポインターが指す場所の内容は変更できません。また、コンパイラーは、エラーメッセージを表示しようとするときに必要です。同じ理由で、からconst char *
への変換char*
は廃止されました。
char* const
ある不変ポインタ(それは他の場所を指すことができない)が、その点があるれる位置の内容を変更可能。
const char* const
不変の文字/文字列への不変のポインタです。
char const *
char *
実行中に変異するとセグメンテーション違反が発生しませんか?
const
、誤ってデータを忘れて変更した場合にコンパイラーにエラーを出させたい場合に使用しますよね?
char *name
name
ポイントする文字、およびポイントする文字を変更できます。
const char* name
name
ポイントする文字を変更できますが、ポイントする文字を変更することはできません。
訂正:ポインターは変更できますが、ポイントする文字は変更できませんname
(https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx、「例」を参照) )。この場合、const
指定子はchar
アスタリスクではなくに適用されます。
MSDNページとhttp://en.cppreference.com/w/cpp/language/declarationsによると、const
前*
はdecl-specifierシーケンスの一部で、const
後*
は宣言の一部です。
宣言指定子シーケンスの後には複数の宣言子を続けることができます。そのため、as およびasをconst char * c1, c2
宣言します。c1
const char *
c2
const char
編集:
コメントから、あなたの質問は、ポインターが文字列リテラルを指しているときの2つの宣言の違いについて尋ねているようです。
その場合、Undefined Behaviorが発生する可能性があるため、指すcharを変更しないでください。文字列リテラルは読み取り専用メモリ領域(実装が定義されている)に割り当てることができ、ユーザープログラムはそれを変更しないでください。そうしようとすると、未定義の動作が発生します。 name
したがって、その場合の唯一の違い(文字列リテラルでの使用法)は、2番目の宣言がわずかな利点をもたらすことです。2番目のケースで文字列リテラルを変更しようとすると、コンパイラーは通常警告を出します。
#include <string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[] = "Sample string";
strcpy(str1,source); //No warning or error, just Undefined Behavior
strcpy(str2,source); //Compiler issues a warning
return 0;
}
出力:
cc1:警告がエラーとして扱われる
prog.c:関数 'main':
prog.c:9:エラー: 'strcpy'の引数1を渡すと、ポインターのターゲットタイプから修飾子が破棄されます
コンパイラは2番目のケースについて警告しますが、最初のケースについては警告しません。
name
。UBになる可能性があります。
char mystring[101] = "My sample string";
const char * constcharp = mystring; // (1)
char const * charconstp = mystring; // (2) the same as (1)
char * const charpconst = mystring; // (3)
constcharp++; // ok
charconstp++; // ok
charpconst++; // compile error
constcharp[3] = '\0'; // compile error
charconstp[3] = '\0'; // compile error
charpconst[3] = '\0'; // ok
// String literals
char * lcharp = "My string literal";
const char * lconstcharp = "My string literal";
lcharp[0] = 'X'; // Segmentation fault (crash) during run-time
lconstcharp[0] = 'X'; // compile error
// *not* a string literal
const char astr[101] = "My mutable string";
astr[0] = 'X'; // compile error
((char*)astr)[0] = 'X'; // ok
char *
、我々は、文字列リテラル(読み取り専用メモリ内に存在している)を変更しようとしているので、値がセグメンテーションフォールトを与える
どちらの場合も、文字列リテラルへのポインタがchar *
またはとして宣言されているかどうかに関係なく、文字列リテラルを変更することはできませんconst char *
。
ただし、ポインタがそうである場合、ポイントconst char *
された値を変更しようとするとコンパイラは診断を行う必要がありますが、ポインタがそうである場合は違いますchar *
。
extern ... name
ているかもしれません*name = 'X';
。「適切なオペレーティングシステム」では失敗する可能性がありますが、組み込みシステムでは、プラットフォーム/コンパイラ固有の何かを実行することを期待しています。
ケース1:
char *str = "Hello";
str[0] = 'M' //Warning may be issued by compiler, and will cause segmentation fault upon running the programme
上記はstrをプログラムのバイナリイメージにハードコード化されたリテラル値「Hello」を指すように設定します。これはメモリ内で読み取り専用としてフラグが立てられ、この文字列リテラルの変更はすべて違法であり、セグメンテーション違反をスローします。
ケース2:
const char *str = "Hello";
str[0] = 'M' //Compile time error
ケース3:
char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
最初は必要に応じて実際に変更でき、2番目は変更できません。const
正しさについて読んでください(違いについていくつかの素晴らしいガイドがあります)。char const * name
あなたがそれを再ポイントできない場所もあります。
問題は、違いは何ですか
char *name
定数文字列リテラルを指す
const char *cname
すなわち与えられた
char *name = "foo";
そして
const char *cname = "foo";
2つの間に大きな違いはなく、どちらも正しいと見なすことができます。Cコードの長いレガシーにより、文字列リテラルのタイプはchar[]
でなくconst char[]
であり、引数を変更しない場合でも、同様にのchar *
代わりに受け入れる古いコードがたくさんありconst char *
ます。
一般に、2の主な違いは、*cname
or cname[n]
はタイプの左辺値に評価されるのconst char
に対し、*name
or name[n]
はタイプの左辺値に評価されchar
、変更可能な左辺値です。割り当てのターゲットが変更可能な左辺値でない場合、診断メッセージを生成するには、適合コンパイラが必要です。タイプの左辺値への割り当て時に警告を生成する必要はありませんchar
。
name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message
どちらの場合も、コンパイラーはコンパイルを停止する必要はありません。への割り当てについて警告を出すだけで十分ですcname[0]
。結果のプログラムは正しいプログラムではありません。コンストラクトの動作は未定義です。クラッシュする可能性があり、さらに悪いことに、クラッシュしない可能性があり、メモリ内の文字列リテラルを変更する可能性があります。
実際、char* name
は定数へのポインタではなく、変数へのポインタです。あなたはこの他の質問について話しているかもしれません。