3

C#、java のデータ型の可変性に関する多くの情報を見つけました。しかし、純粋な C についてはどうでしょうか。

たとえば、intC ではデフォルトで不変ですか?

たとえば、次のコード例を見てください。

#include <stdio.h>

int main()
{
  int a,b,c;
  b=0;
  c=0;
  a=b+c;
  b=1;
  c=2;

  printf("1st time %d\n",a);//gives out 0
  c=3;
  printf("2nd time %d",a);//gives out 0
  return 0;
}

上記のコードは、普通のintオブジェクトが不変であることを示していますね。

4

4 に答える 4

4

Ordinary int is mutable. An entity that is (not merely claimed to be at some point, but "really is") const is not-mutable-in-theory and if the hardware and software cooperate, often not-mutable-in-fact as well.

Defining a variable using the const qualifier makes it "really" const:

const int c3 = 3;
void f(void) {
    const int c4 = 4;
    ...
}

With "tricky" code (casting away the const-ness) you can convince the system to write, or attempt to write, new values into c3 and/or c4:

void f(void) {
    const int c4 = 4;
    int *p;

    p = (int *)&c3;
    *p = 99;
    printf("c3 is now %d\n", c3);
}

If you call f() you may, on some systems, find that c3 changes and becomes 99. On other systems you may get a "segmentation fault" or other run-time error.

Change the references to use c4 and the same things can happen—although in practice, few if any systems produce a run-time error. However, you may observe something else entirely: instead of printing c4 is now 99 you may get c4 is now 4.

This last can happen because the compiler is allowed to assume that, having made c4 a const int with value 4, you, the programmer, never changed it. That *p = 99 must not have changed it (even if it did), so the call to printf can be replaced with a different call that just prints 4.

The same is generally true of references to c3: the compiler can assume that since you promised never to change it, you never actually did change it. This can produce surprising results, such as: p == &c3 being true, c3 being 3, and *p being 99. But a run-time error is pretty likely, because most modern compilers and OSes cooperate to stick c3 into a read-only region.

When string literals produce arrays (which is most of the time), C has a quirk. These arrays are not const-qualified, but the characters making up the array are read-only anyway (at least in principle, as with const int c3 = 3;). Like c3, most modern systems manage to make them "really read-only".

(String literals do not produce arrays when they are used as initializers for objects of type array of char. Compare:

char *ronly = "this string is read only";
char rwarray[] = "this string is read/write";

Here ronly is a pointer, not an array, so the string literal produces an array and ronly points to the first character of that array. The underlying array is read-only, even though its type is char [25]. But rwarray is an array, not a pointer, so the string literal fills it in—and sets its size to 26—and it is mutable. You would have to write const char roarray[] = ... to make it immutable. [Some like to spell the type char const [], with the const coming after the data-type. These mean the same thing.])

于 2013-05-31T05:56:52.370 に答える
3

ミュータブルであることの意味、または少なくとも手続き型言語の仕組みを根本的に誤解していると思います。a、b、および c の値がコメント化されたコードを次に示します。

#include <stdio.h>

int main(void) // Good practice to declare main with `(void)` instead of ()
{
  int a,b,c;                 // a,b, and c are garbage values (whatever was left in memory)
  b=0;                       // a == garbage, b == 0, c == garbage
  c=0;                       // a == garbage, b == 0, c == 0
  a=b+c;                     // a == 0, b == 0, c == 0
  b=1;                       // a == 0, b == 1, c == 0
  c=2;                       // a == 0, b == 1, c == 2

  printf("1st time %d\n",a);
  c=3;                       // a == 0, b == 0, c == 3 
  printf("2nd time %d",a);
  return 0;
}

が割り当てられると、変更されるため、a魔法のように更新されることはありません。それは、可変性と不変性とは何の関係もありません。実際、b と c を 0 に代入し、後でそれぞれ 1 と 2 に再代入することで、s (および実際には宣言されていない C のすべてのデータ型) が実際に変更可能であることを示しました。cbintconst

于 2015-11-22T19:35:55.090 に答える
0

これは答えではありませんが、私はコメントしたり投票したりするのに十分な「評判」ではありません。

  1. 上記の @torek による C の constness に関する素敵な記事 (また、オンライン テスターが多肢選択式の質問にそのような生の質問を含めない理由もあります)。

  2. 「変更可能」という用語が(JavaScriptで「プロトタイプ」オブジェクトを使用して)それにプロパティを追加できることを意味する(私が思うに)JavaScriptの初心者として。

いずれにせよ、質問で書いたコード部分では、ステートメント a=b+c; は、コード ブロック内のその時点の 'b' と 'c' の値(どちらも 0) で 'a' の値のみを変更し、3 つの変数すべてが元のアドレスを保持します。したがって、ステートメントの後で代入変数を変更しても、「a」の値には影響しません。そしてCでは、この事実はそれを「不変」にはしません。つまり、値を変更することはできません。

于 2015-01-29T08:28:21.423 に答える