1

我需要一个解释。我搜索了一个答案,但找不到一个。

问题如下:我正在练习书中的练习:“工程师编程”AR Bradley 第 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,所以强制转换(长)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

从我的角度来看,它打印分配值的唯一方法是在指针中手动将它们分配为地址。

例子

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

将在屏幕上打印100,但尝试取消引用它会导致(很可能)分段错误。

因此,考虑到这个过程的风险,以及在 void* 中保存长整数的废话,我什至反对将其视为有用的代码。

于 2013-10-24T07:03:38.167 回答
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 回答