{"id":1293,"date":"2015-04-11T00:01:57","date_gmt":"2015-04-11T07:01:57","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=1293"},"modified":"2015-04-04T13:00:28","modified_gmt":"2015-04-04T20:00:28","slug":"quicksorting-strings-pointer-edition","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=1293","title":{"rendered":"Quicksorting Strings, Pointer Edition"},"content":{"rendered":"<p>I&#8217;ll confess that when I use a quicksort to sort and array of strings, I don&#8217;t use the C Library&#8217;s <em>qsort()<\/em> function. No, I write my own. The problem is that when sorting an array of strings, the <em>qsort()<\/em> function&#8217;s <em>compar<\/em> argument is a pain in the butt to craft properly.<br \/>\n<!--more--><br \/>\nAn array of strings is an array of pointers. Because an array itself is a pointer, the end result is a pointer to a pointer, or the ugly <code>**<\/code> thing, which I&#8217;ve written about elsewhere on this site.<\/p>\n<p>The beauty of the pointer array is that the strings themselves aren&#8217;t messed with; only the pointers are sorted (based on the strings). For the <em>qsort()<\/em> function, the problem is how to translate an array of pointers into something that the <em>compare()<\/em> function swallows in an obedient manner.<\/p>\n<p>As a review, here is the pattern normally used in the <em>compare()<\/em> function:<\/p>\n<pre><code>int compare(const void *a, const void *b)\r\n{\r\n    return( *(<em>type<\/em> *)a - *(<em>type<\/em> *)b);\r\n}<\/code><\/pre>\n<p>The function&#8217;s two arguments never change. They are <em>const void<\/em> types. <em>const<\/em> means that the variable&#8217;s value cannot change; it&#8217;s constant. <em>void<\/em> identifies the variables as pointers of a non-specific type. The variable is typecast properly within the function, typically within the <em>return<\/em> statement, as shown above.<\/p>\n<p>With a pointer-to-a-pointer variable, you would think you could get away with something like the following to compare two strings:<\/p>\n<pre><code>    return( strcmp((char **)a,(char **)b) );<\/code><\/pre>\n<p>Alas, no: That doesn&#8217;t work. It&#8217;s essentially a stab in the dark &mdash; a good stab, close to the solution, but wrong.<\/p>\n<p>The problem is the <em>const<\/em> keyword. The variables must still be treated as constants, so that keyword must be part of the solution. The typecast for an array of strings is correctly <code>(char **)<\/code>, but that still doesn&#8217;t handle the fact that the <em>strcmp()<\/em> function needs pointers, not pointer-pointers. So another asterisk is required to make that function happy.<\/p>\n<p>Yes, 10,000 monkeys sitting at keyboards with an abundance of asterisk keys would eventually divine a solution. Rather than wait that long, behold my solution, using similar code as presented in <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1287\">last week&#8217;s Lesson<\/a>, but using pointer notation to create the array of strings:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &ltstring.h&gt;\r\n\r\n#define C 15\r\n\r\nint compare(const void *a, const void *b);\r\n\r\nint main()\r\n{\r\n    char *crew[] = {\r\n        \"Thorin\",   \"Fili\", \"Kili\",\r\n        \"Bilbo\",    \"Dori\", \"Balin\",\r\n        \"Dwalin\",   \"Ori\",  \"Gloin\",\r\n        \"Bifur\",    \"Nori\", \"Bofur\",\r\n        \"Bombur\",   \"Oin\",  \"Gnadalf\"\r\n    };\r\n    int x;\r\n\r\n    <span class=\"comments\">\/* print original strings *\/<\/span>\r\n    printf(\"Original: \");\r\n    for(x=0;x&lt;C;x++)\r\n        printf(\"%s \",crew[x]);\r\n    putchar('\\n');\r\n\r\n    <span class=\"comments\">\/* quicksort the list *\/<\/span>\r\n    qsort(crew,C,sizeof(char *),compare);\r\n\r\n    <span class=\"comments\">\/* print sorted strings *\/<\/span>\r\n    printf(\"  Sorted: \");\r\n    for(x=0;x&lt;C;x++)\r\n        printf(\"%s \",crew[x]);\r\n    putchar('\\n');\r\n\r\n    return(0);\r\n}\r\n\r\nint compare(const void *a, const void *b)\r\n{\r\n    const char **pa,**pb;\r\n\r\n    pa = (const char **)a;\r\n    pb = (const char **)b;\r\n    return( strcmp(*pa,*pb) );\r\n}<\/pre>\n<p>To make the code in the <em>compare()<\/em> function more readable, I use two pointer-pointer variables, <code>pa<\/code> and <code>pb<\/code>. These are assigned the values of the two pointers passed to the function, <code>a<\/code> and <code>b<\/code>, both of which must be typecast to the <code>**<\/code> thing; an array of pointers. (That&#8217;s what&#8217;s being sorted.)<\/p>\n<p>Once <code>pa<\/code> and <code>pb<\/code> are assigned, they can then be used in the <em>strcmp()<\/em> function, nestled in the <em>return<\/em> statement. The pointer operator <code>*<\/code> is required inside the <em>strcmp()<\/em> function because array elements are being sorted, not the entire array, which is how the compiler sees a <code>**<\/code> variable.<\/p>\n<p>Yes, that&#8217;s confusing! Don&#8217;t feel bad if you&#8217;re intimidated by the entire thing.<\/p>\n<p>Of course, my solution above is written for readability. You can reduce the <em>compare()<\/em> function to a single return statement, if you&#8217;re really crazy:<\/p>\n<pre><code>    return( strcmp( *((const char **)a), *((const char **)b)) );<\/code><\/pre>\n<p>I don&#8217;t fault anyone for not coming up with this solution on their own. It is not easy! But that&#8217;s the way it&#8217;s done. Even advanced C programmers write down stuff like this so that they don&#8217;t have to re-think the solution later.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s your old nemesis, the <code>**<\/code> thing. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1293\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-1293","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1293","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1293"}],"version-history":[{"count":5,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1293\/revisions"}],"predecessor-version":[{"id":1321,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1293\/revisions\/1321"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1293"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1293"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1293"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}