web-dev-qa-db-ja.com

C ++およびCの関数パラメーターとしてのconst intとint const

簡単な質問:

int testfunc1 (const int a)
{
  return a;
}

int testfunc2 (int const a)
{
  return a;
}

これらの2つの機能はすべての面で同じですか、それとも違いがありますか?私はC言語の答えに興味がありますが、C++言語に何か面白いことがあれば、私も知りたいです。

109

const TおよびT constは同一です。ポインター型では、より複雑になります。

  1. const char*は、定数charへのポインターです。
  2. char const*は、定数charへのポインターです。
  3. char* constは(可変)charへの定数ポインターです。

つまり、(1)と(2)は同じです。ポインターを(ポインティではなく)constにする唯一の方法は、接尾辞constを使用することです。

これが、多くの人がconstを常にタイプの右側に配置することを好む理由です(「East const」スタイル)。初心者に簡単に教えることができます)。

168
Konrad Rudolph

コツは、宣言を逆方向(右から左)に読むことです:

const int a = 1; // read as "a is an integer which is constant"
int const a = 1; // read as "a is a constant integer"

両方とも同じものです。したがって:

a = 2; // Can't do because a is constant

逆読みのトリックは、次のようなより複雑な宣言を扱う場合に特に役立ちます。

const char *s;      // read as "s is a pointer to a char that is constant"
char c;
char *const t = &c; // read as "t is a constant pointer to a char"

*s = 'A'; // Can't do because the char is constant
s++;      // Can do because the pointer isn't constant
*t = 'A'; // Can do because the char isn't constant
t++;      // Can't do because the pointer is constant
323
Ates Goral

違いはありません。どちらも、「a」は変更できない整数であると宣言しています。

違いが現れるのは、ポインターを使用するときです。

これらの両方:

const int *a
int const *a

「a」を、変化しない整数へのポインタとして宣言します。 「a」は割り当てることができますが、「* a」は割り当てることができません。

int * const a

「a」が整数への定数ポインタであることを宣言します。 「* a」は割り当てることができますが、「a」は割り当てることができません。

const int * const a

「a」が定数整数への定数ポインタであることを宣言します。 「a」も「* a」も割り当てられません。

static int one = 1;

int testfunc3 (const int *a)
{
  *a = 1; /* Error */
  a = &one;
  return *a;
}

int testfunc4 (int * const a)
{
  *a = 1;
  a = &one; /* Error */
  return *a;
}

int testfunc5 (const int * const a)
{
  *a = 1;   /* Error */
  a = &one; /* Error */
  return *a;
}
13
Andru Luvisi

Prakashは、宣言が同じであるということは正しいですが、ポインターのケースについてもう少し説明することが適切かもしれません。

「const int * p」は、そのポインターを使用してintを変更できないintへのポインターです。 「int * const p」は、別のintを指すように変更できないintへのポインターです。

http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.5 を参照してください。

7
Fred Larson

const intint constと同一です。Cのすべてのスカラー型で真です。一般に、Cの値渡しにより、スカラー関数パラメーターをconstとして宣言する必要はありません。セマンティクスとは、変数に対する変更は、それを囲む関数に対してローカルであることを意味します。

5
Emerick Rogul

それらは同じですが、C++では常に右側でconstを使用する正当な理由があります。 constメンバー関数mustは次のように宣言されるため、どこでも一貫性が保たれます。

int getInt() const;

関数のthisポインターをFoo * constからFoo const * constに変更します。 こちらをご覧ください

4
Nick Westgate

これは直接的な答えではなく、関連するヒントです。物事を真っ直ぐにするために、私は常に対流「put const on the outside」を使用します。「outside」とは、左端または右端を意味します。そうすれば混乱はありません-constは最も近いもの(型または*)。例えば。、



int * const foo = ...; // Pointer cannot change, pointed to value can change
const int * bar = ...; // Pointer can change, pointed to value cannot change
int * baz = ...; // Pointer can change, pointed to value can change
const int * const qux = ...; // Pointer cannot change, pointed to value cannot change
4
Pat Notz

はい、それらはintだけで同じです

int*

3
prakash

この場合、それらは同じだと思いますが、順序が重要な例を次に示します。

const int* cantChangeTheData;
int* const cantChangeTheAddress;
3
user7545