void指向函数的指针

时间:2013-10-24 06:06:18

标签: c function-pointers void-pointers

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

问题如下: 我正在从书中进行练习:“为工程师编程”A.R.布拉德利第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我传递无效指针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

我会得到价值。为什么第一个代码部分打印的值不是地址? 我想我没有看到什么,所以这就是为什么我很困惑。请帮助:)

2 个答案:

答案 0 :(得分:0)

从我的观点来看,它打印指定值的唯一方法是在指针中手动将它们指定为地址。

示例

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

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

因此,考虑到这个过程的风险,以及在虚假中保持长整数的无意义*我甚至反对将此视为有用的代码。

答案 1 :(得分: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]

的副本