0
char * c = "world"; // works fine 

しかし

int * p = 10; // throws an error

次のようにする必要があります

int * p = new int(10); // in C++
int * p = (int*) malloc(1 * sizeof(*int)); // in C

ポインターが何らかのメモリに割り当てられるか、何らかのアドレスを参照する必要がある場合、メモリを割り当てずに文字列を文字ポインターに格納できるのはなぜですか?整数データ型ではないのはなぜですか?

4

3 に答える 3

3

charC および C++は、指定された初期値を持つ配列型の値を作成するための構文、文字列リテラルをたまたま提供しています。

C では、文字列リテラル"world"の型はchar[6](文字列の長さの 5 プラス終端の 1 '\0') です。C++ では、タイプconst char[6]です。この違いは歴史的な理由によるものです。どちらの言語でも、文字列リテラルは常に読み取り専用として扱う必要があります。

また、配列型の式と同様に、ほとんどのコンテキストで、最初の要素へのポインターに暗黙的に変換されます。それが理由です

const char *c = "world";

有効です。文字列リテラル"world"自体が無名配列オブジェクトを作成し、初期化によってc配列オブジェクトの最初の要素がポイントされます。

type のオブジェクトを作成するためのそのような組み込み構文はたまたまありませんint

いや、実はあります。C99 は複合リテラルを追加し、次のように記述できるようにしました。

int *p = (int[]){ 10 };

int[1]への同じ暗黙的な変換で、タイプ の配列オブジェクトを作成しますint*。(C++ には複合リテラルがありません。) (配列オブジェクトの有効期間は、それが表示されるコンテキストに依存します。関数本体内にある場合、配列は、囲んでいるブロックが終了すると存在しなくなります。文字列リテラルは、他方では一方、静的な保存期間があり、プログラムの実行全体にわたって存在します。)

ちなみに、これ:

int * p = (int*) malloc(1 * sizeof(*int)); // in C

間違っています; あなたが欲しいint*、そうではありません*int。しかし、次のように書いたほうがよいでしょう:

int *p = malloc(sizeof *p));

C では結果のキャストmallocは不要であり、場合によってはエラーを隠すことができます。を使用sizeof *pすると、コードがより堅牢になります。後でapからint*adouble*などに変更する場合、タイプを 1 か所で変更するだけで済みます。

于 2013-10-27T20:49:15.217 に答える
1

定義により、文字列リテラルにはchar*文字列の最初の文字へのポインターである型があるためです。

于 2013-10-27T20:23:19.803 に答える
1

Pointer 変数には address を格納する必要があります。

char * c = "world"; // works fine

"world"はプログラムの読み取り専用ブロックにメモリが割り当てられているため、"world"何らかのアドレスを取得し、このアドレスはポインターに格納されますc

int * p = 10; // throws an error

10は定数整数であり、まだメモリが割り当てられていないため、アドレスがありません。アドレスではないため10、ポインターに定数を格納することはできません。p

それが私たちがする理由です

int * p = new int(10); // in C++

int * p = (int*) malloc(1 * sizeof(int)); // in C

これにより、 value を持つメモリが integer に割り当てられ10、その整数のp正しいアドレスが格納されます

于 2013-10-27T20:30:01.727 に答える