c互換性のない型に配置問題へのポインター?
質問
こんにちはんとCであると思いますが、どのように割当についてのポインタ.
struct foo
{
int _bar;
char * _car[SOME_NUMBER]; // this is meant to be an array of char * so that it can hold pointers to names of cars
}
int foofunc (void * arg)
{
int bar;
char * car[SOME_NUMBER];
struct foo * thing = (struct foo *) arg;
bar = thing->_bar; // this works fine
car = thing->_car; // this gives compiler errors of incompatible types in assignment
}
車-_carて同宣言では、なぜ私はこの映画に影響をうけましたエラーにつなのか。私の推測では、あなたとのポインタ(なポインタ配列のchar*かな?) でもなぜここが問題です。
私が宣言された char * car;
の代わりに char * car[MAXINT];
で収集す。もしっかり身につけるたどのように役に立ち時以降ったり、特定の情報利用の指標となりますので面倒にアクセスする情報です。実際、僕らず、心配や不安な場合、私は、適切な方法で、ん、ありがとうございますので、よりハイアットグランチ文字列の代わりに配列のchar*?
編集:なかった平均の利用INT_MAX(最大値のint)をかけて食べるという習慣がありその他のint20.
解決
を作成する新しい配列のサイズMAXINT.と思うのを作りたいポインタ配列のサイズMAXINT.
を指すポインタ配列のchar*'s:
以下では、配列のサイズMAXINT char*要素
char * car[MAXINT];
以下にポインタ:配列のサイズMAXINT char*要素
char* (*car)[MAXINT];
法は以下のとおりですセットを指すポインター:配列のサイズMAXINT char*要素
char* (*car)[MAXINT];
car = &arg->_car;
その他の構文エラーの問題:
- 必要なものをセミコロンの後の構造体定義で設定します。
- 使用
foo*
ないfoo
.でなければならないと考えてお:
struct foo* thing = (struct foo *) arg;
- 使用
thing
ないarg
:
bar = thing->_bar;
car = thing->_car;
他のヒント
car
と_car
両方の配列であり、そしてCであなたができない割り当てアレイ(アレイは、構造体(または共用体に埋め込まれている場合を除く)して、構造の割り当てを行う)。
また、チャーへのポインタのアレイではなく、チャーの配列へのポインタです。あなたはコードで書かれていることはあなたが望むもの、おそらくです - あなたは、アレイ内のMAXINT名までへのポインタを格納することができます。ただし、あなたが正しくタイプを記述する必要があります - 。文字またはcharポインタへのポインタの配列として
文字の配列へのポインタは次のようになります。
char (*car)[MAXINT];
と文字ポインタの配列をポイント(おかげで、ブライアン)は次のようになります:
char *(*car)[MAXINT];
MAXINTのように注意してください。それは
(少なくとも2 31 -1である<values.h>
としてLinux上で、MAXINT
定義INT_MAX
、)非常に大きなアレイとすることができます
<時間>
のようなコードになります。
をstruct foo
{
int _bar;
char * _car[MAXINT];
}
int foofunc (void * arg)
{
int bar;
char * car[MAXINT];
struct foo thing = (struct foo *) arg;
bar = arg->_bar; // this works fine
car = arg->_car; // this gives compiler errors of incompatible types in assignment
}
バーへの割り当ても車はいずれも、すべてでコンパイルする必要があります - arg
はvoid *
です。あなたはおそらく、いくつかの形状または形態でthing
を使用することを意味しました。ブライアンが指摘したように、そこに問題があまりにも、あります:
あなたはどちらか欲しいます:
int foofunc(void *arg)
{
int bar;
char *car[MAXINT];
struct foo thing = *(struct foo *)arg;
bar = thing._bar; // this works fine
car = thing._car; // this is still an array assignment
...other code using bar and car...
}
それともあなたが欲しいます:
int foofunc(void *arg)
{
int bar;
char *car[MAXINT];
struct foo *thing = (struct foo *) arg;
bar = thing->_bar; // this works fine
car = thing->_car; // this is still an array assignment
...other code using bar and car...
}
あるいは、実際ます:
int foofunc(void *arg)
{
struct foo *thing = (struct foo *) arg;
int bar = thing->_bar; // this works fine
char *car[MAXINT] = thing->_car; // this is still an array assignment
...other code using bar and car...
}
<時間>
最後に、配列代入を扱う、Cであなたが合理的にこれを行うにmemmove()
を使用することができます:
int foofunc(void *arg)
{
struct foo *thing = (struct foo *) arg;
int bar = thing->_bar; // this works fine
char *car[MAXINT];
memmove(car, thing->_car, sizeof(car));
...other code using bar and car...
}
領域が重複コピーする場合memcpy()
がないのに対し、同様の機能memmove()
は、信頼性のある意味を持ちません。常に正しく動作するため、常にmemmove()
を使用する方が簡単です。 C ++では、memmove()
(またはmemcpy()
)を使用して慎重にする必要があります。このコードでは、それは安全で十分だろうが、なぜ理解することは非自明である。
はあなたがちょうどここにポインタをコピーしていることを認識する必要があります - あなたは、ポインタが指し示すという文字列をコピーされていません。何か他のものは、それらの文字列を変更した場合、それはcar
経由で見られた値と、呼び出し元のコード内の変数の両方に影響します。
最後に一つのポイント - 今の:あなたはあなたがvoid *
として関数に引数を必要としていますか?それは、機能ではなく、「struct foo *
」(あるいは「const struct foo *
」)を取るように宣言されている場合に防止することができ虐待のすべての種類のコードを開きます。
あなたは、アレイにあなたがやっている方法を割り当てることはできません。あなたは、要素ごとのコピーを行うことができます。
for(int i = 0; i < MAXINT; i++)
{
car[i] = (arg->_car)[i]
}
の文字列が一定でない場合ならば、あなたは利用strcpy
に必要があるかもしれないことに注意ます。
Cにおける配列表記は、合法的に混乱されます。あなたのコードは、あなたがそれが意味どう思うかという意味ではありません。
arg->_car
手段「配列_car
のアドレス」。同様に、car
手段「アレイcar
のアドレス」。あなたが車に_carの内容をコピーしようとしている場合、これはそれを行います。
memcpy(car, _car, MAXINT);
しかし、あなたの本当の問題は、私が思うに、「文字列のリストを格納するための最良の方法は何ですか?」されこの答えは次のとおりです。ダイナミックリスト(あなたがアイテムを追加すると、自動的に成長する1)
あなたはこのようにそれを宣言するだろう。
#define CARSIZE 65
int numCars = 0;
char **car; /* a list of addresses, each one will point to a string */
車を追加するには:
char *newCar = malloc(CARSIZE); /* make room */
strncpy(newCar, "Mercedes", CARSIZE); /* newCar has the address of the string */
car[numCars++] = newCar; /* store it */
車のリストに:
int n;
for (n = 0; n < numCars; ++n)
printf("%s\n", car[n]);
Nの位置に車を削除するには:
free(car[n]); /* release the memory */
/* condense the list of pointers */
for ( ; n < numCars - 1; ++n)
car[n] = car[n+1];
これはCで完全にルーチンである注:私はすべての*正しい場所にいると約束することはできませんので、の上では、私の頭の上からで、作業プログラムからコピーされません。私はあなたを与えたくないので、私は、これは宿題である疑いがあるのすべての ...