#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    3

    Correct use of * operator ?


    In the first line, the "*" operator is in the middle:

    Code:
    int compare (const void * a, const void * b)
    {
      return ( *(int*)a - *(int*)b );
    }
    
    /*It's a compare fuction for qsort()*/
    Where EXACTLY does the "*" operator belong: is it (void*----a) OR (void-----*a) ????

    And what is the meaning of each ?

    Is putting it in the middle different from both forms above?
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    159
    Rep Power
    19
    It doesn't really matter to the compiler where you palce the pointer.

    The following are all the same to the compiler:
    Code:
    int compare (const void* a, const void* b);
    int compare (const void *a, const void *b);
    int compare (const void * a, const void * b);
    My recommendation is to pick the version that makes the most sense to you and use that style consistently.

    Jim
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    3
    Originally Posted by jimblumberg
    It doesn't really matter to the compiler where you palce the pointer.

    The following are all the same to the compiler:
    Code:
    int compare (const void* a, const void* b);
    int compare (const void *a, const void *b);
    int compare (const void * a, const void * b);
    My recommendation is to pick the version that makes the most sense to you and use that style consistently.

    Jim
    Is it all the same, EXCEPT for when CASTING ?

    (char*)a is NOT(??) equal to: (*char)a
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    It's optional. Either way will work, even sticking it in the middle because you're afraid to commit. And being a personal choice, you can get into religious wars over it, much like over the placement of the open brace (hiding it at the end of the line as in K&R style vs placing it out in the open as in Allman style).

    Perhaps considering this declaration would help:
    Code:
        char* cp, ch, c2;
    What datatypes are cp, ch, and c2? cp is a char pointer, whereas both ch and c2 and char. Was that what you had expected it to mean?

    Now, the placement of the asterix there would lead us to associate it with what it's pointing to, thus misleading us to think that all the variables declared there would be of the same type, char pointers. But they're not.

    Now look at this one:
    Code:
        char *cp, ch, c2;
    Here, the placement of the asterix associates it in our minds with the cp, but not with the other two variables. And which is also much closer to what's actually being said there.

    We'd have to look at the syntax rules, but what I think we'd see is that the declaration syntax would this: <datatype>*<identifier>. Now, whitespace is the common delimiter between tokens, but in this case the asterix itself also acts as a delimiter. Hence, these four possibilities would all fit the syntax and would all work:
    char *cp;
    char* cp;
    char * cp;
    char*cp;

    Compare that with arithmetic expressions:
    (a + b)
    (a+b)
    (a +b)
    (a+ b)
    Those are all the same expression.

    One way to think about the use of the comma operator is that the asterix was part of the declaration of cp, but it wasn't part of the delcarations of ch nor of c2. But again we'd have to walk through the syntax.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    159
    Rep Power
    19
    Is it all the same, EXCEPT for when CASTING ?

    (char*)a is NOT(??) equal to: (*char)a
    You're missing the key difference.

    Look at this snippet:
    Code:
     int compare (const void* a, const void* b)
    {
      return ( *(int*)a - *(int*)b );
    }
    The placement of the pointer is after the type. The leading pointer is followed by the parentheses. These parentheses are an important part of the equation. You are casting a and b from a void* to an int*, and since you want to work with the actual value not the pointer you need to use indirection so you need to add a pointer. To bind this pointer to a you need to use the parentheses.


    Jim
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Originally Posted by C learner
    Is it all the same, EXCEPT for when CASTING ?

    (char*)a is NOT(??) equal to: (*char)a
    When you cast, you use parenthses.

    However, what you are proposing there are not the same:
    (char*)a -- you are casting a to be a char pointer
    (*char)a -- you are casting a to be a dereferenced char

    To be quite honest, I cannot even begin to imagine what a "derefereced char" could possibly be.


    PS
    An analogy keeps popping up in my head, though it's in German. I guess that's because I keep remembering the movie scene where I heard the second one.

    You could say, "Gar nicht", which means something like "most certainly not!"

    Or you could say "Nicht gar", which means "not quite", almost but it's not quite there.

    Same words, but with reversed order and also having opposite meanings.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    109
    Rep Power
    3
    I think i get it. Thanks a lot.

    Another question if you don't mind :) :

    In the qsort() function tutorial they say that the base(the first arg passed to it) must be a :Pointer to the first object of the array to be sorted, converted to a void*.

    Converted to void?? but when i pass a regular pointer not converted to void it also works. how come ?

    Code:
    int arr[]={9, 8, 7, 6, 5, 4};
    
    int *ARR[]={arr, arr+1, arr+2, arr+3, arr+4, arr+5};
    
    
       
    int compare (const void * a, const void * b)
    {
      return ( *(int*)a - *(int*)b );
    }
     
      
        qsort(*ARR,6,sizeof(int),compare);
    I don't see where ARR is being converted to void?? (the code above works)

IMN logo majestic logo threadwatch logo seochat tools logo