1

説明が必要です。答えを探しましたが、見つかりませんでした。

問題は次のとおりです。私は本からの演習に取り組んでいます:「エンジニアのためのプログラミング」AR Bradley Chapter 7 コードの一部は次のとおりです。

struct _fifo {
   unsigned capacity;
   unsigned head;
   unsigned tail;
   void * data[0];
};

fifo newFifo(int capacity) {
   // The capacity of a circular buffer is one less than one
   // would think: if the user wants a given capacity, the
   // required array is one cell larger.
   capacity++;

   fifo q = (fifo) malloc(sizeof(struct _fifo) + capacity * (sizeof(void *)));
   q->capacity = (unsigned) capacity;
   q->head = 0;
   q->tail = 0;
   return q;
}

int putFifo(fifo q, void * e) {

   if ((q->head+1) % q->capacity == q->tail) // full?
      return -1;
   q->data[q->head] = e;
   q->head = (q->head+1) % q->capacity;
   return 0;
}

typedef void (*printFn) (void*);

int printFifo(fifo q, printFn f) {

   unsigned i;
   for (i = q->tail; i != q->head; i = (i+1) % q->capacity) {
      f(q->data[i]);
   }
   return 0;
}

static void printLong(void * e) {
   // %ld tells printf to print a long integer
   printf("%ld", (long) e);
}

int main() {
   fifo longq;
   longq = newFifo(3);

   printFifo(longq, printLong);
   return 0;
}

私の質問は次のとおりです。関数 printLong で void ポインター e を渡しているので、キャスト (long) e は e のアドレスを作成しますか? 印刷されたアドレスではなく、データの値を取得しているのはなぜですか?

たとえば、これを行うと、値ではなくアドレスが出力されます。

typedef void (*printFn) (void*);

static void printLong (void * e) {
   printf("%ld", (long) e);
}

int printL (void* l, printFn f) {
   f(l);
}

int main() 
{
   long a = 5;
   long* l = &a;

   printf("%ld\n", *l);
   printL(l, printLong);

   return 0;
}

しかし、私がキャストした場合

*(long*) e

値を取得します。最初のコード部分がアドレスではなく値を出力するのはなぜですか? 何も見えないので、混乱していると思います。助けてください :)

4

2 に答える 2

0

関数printLongでは、voidポインターeを渡しているので、キャスト(ロング)eはeのアドレスを作成しますか?印刷されたアドレスではなく、データの値を取得しているのはなぜですか?

番号。ポインターを long int にキャストします。e のアドレスを取得したい場合は、代わりに &e を使用します。しかし、 e はすでに関数のアドレスです...スタック上にあるため、引数のアドレスを取得しても意味がありません。

したがって、基本的に、関数について誤解している可能性があると思います。関数名は var 名とは異なります。

  • var_name には値があり、&var_name を使用してアドレスを取得します
  • function_name 自体は関数
    実装のアドレスの値を持ち、&function_name は同じ
    値 (同じアドレス) を返します。

アップデート:

f(q->data[i]); と呼びます。printLong (void* e) に到達するには - e は q->data[i] を指しているべきではありませんか?

C では、関数の引数は値渡しです。q->data[i] の値は printLong() に渡されるため、引数 e は q->data[i] と同じ値 (同じアドレス) になります。e は q->data[i] のコピーです

于 2013-10-24T07:47:42.067 に答える
0

私の観点からは、割り当てられた値を出力する唯一の方法は、ポインターでアドレスとして手動で割り当てることです。

void * ptr=100;
printf("%ld", (long)ptr);

画面に表示100されますが、逆参照しようとすると、(ほとんどの場合) セグメンテーション違反が発生します。

したがって、この手順のリスクと、長い整数を void* に保持することのナンセンスを考慮すると、これを有用なコードと見なすことさえ反対です。

于 2013-10-24T07:03:38.167 に答える