Domanda

I need an explanaton. I searched for an answer but couldn't find one.

The problem is as follows: I'm working on exercises from the book: "Programming for Engineers" A.R. Bradley Chapter 7 Here's part of the code:

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;
}

My question is this: in function printLong i'm passing void pointer e so does the cast (long) e makes that adress of e? how come i'm getting a value of data and not the address printed?

for example if i do this i'm getting the address printed not the value:

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;
}

but if i cast

*(long*) e

i'll get the value. How come first code part prints the value not the address? I guess i don't see something so that's why i'm confused. Please help :)

È stato utile?

Soluzione

in function printLong i'm passing void pointer e so does the cast (long) e makes that adress of e? how come i'm getting a value of data and not the address printed?

no. It casts the pointer to a long int. If you want to get the address of e, use &e instead. But e is already the address of a function... i see no point in getting the address of a argument because it is on the stack.

So basically I guess you might have some misunderstanding on functions.A function name is not like a var name:

  • var_name has a value and you use &var_name to get the address
  • function_name itself has the value of the address the function
    implementation and &function_name would return the same
    value(the same address).

UPDATE:

I call f(q->data[i]); to get to printLong (void* e) - so shouldn't e be pointing to q->data[i] ?

In C, function arguments are passed by value. The value of q->data[i] is passed to printLong() so the argument e would have the same value(the same address) as q->data[i]. so e is a copy of q->data[i]

Altri suggerimenti

From my point of view the only way it prints assigned values is by assigning them as addresses manually in your pointer.

Example

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

will print 100 on the screen, but trying to dereference it will cause (most likely) segmentation fault.

So considering the risks of this procedure and, well, nonsense of holding long integers in void* I'm against even considering this as useful piece of code.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top