{"id":533,"date":"2021-12-31T18:00:28","date_gmt":"2021-12-31T10:00:28","guid":{"rendered":"https:\/\/blog.liuyingjie.com.cn\/?p=533"},"modified":"2023-08-17T14:25:51","modified_gmt":"2023-08-17T14:25:51","slug":"kr2-solutions-chapter-2-types-operators-and-expressions","status":"publish","type":"post","link":"https:\/\/blog.liuyingjie.com.cn\/?p=533","title":{"rendered":"K&#038;R2 solutions: Chapter 2 &#8211; Types, Operators and Expressions"},"content":{"rendered":"\n<p>Exercise 2-1. Write a program to determine the ranges of <code>char<\/code> , <code>short<\/code> , <code>int<\/code> , and <code>long<\/code> variables, both <code>signed<\/code> and <code>unsigned<\/code> , by printing appropriate values from standard headers and by direct computation. Harder if you compute them: determine the ranges of the various floating-point types.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">#include&lt;stdio.h&gt;\n#include&lt;limits.h&gt;\n\n\/* determine ranges of types *\/\nmain() {\n    \/* signed types *\/\n    printf(\"signed char min = %d\\n\", SCHAR_MIN);\n    printf(\"signed char max = %d\\n\", SCHAR_MAX);\n    printf(\"signed short min = %d\\n\", SHRT_MIN);\n    printf(\"signed short max = %d\\n\", SHRT_MAX);\n    printf(\"signed int min = %d\\n\", INT_MIN);\n    printf(\"signed int max = %d\\n\", INT_MAX);\n    printf(\"signed long min = %d\\n\", LONG_MIN);\n    printf(\"signed long max = %d\\n\", LONG_MIN);\n\n    \/* unsigned types *\/\n    printf(\"unsigned char max = %u\\n\", UCHAR_MAX);\n    printf(\"unsigned short max = %u\\n\", USHRT_MAX);\n    printf(\"unsigned int max = %u\\n\", UINT_MAX);\n    printf(\"unsigned long max = %lu\\n\", ULONG_MAX);\n}<\/code><\/pre>\n\n\n\n<p>Output Result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">signed char min = -128\nsigned char max = 127\nsigned short min = -32768\nsigned short max = 32767\nsigned int min = -2147483648\nsigned int max = 2147483647\nsigned long min = -2147483648\nsigned long max = -2147483648\nunsigned char max = 255\nunsigned short max = 65535\nunsigned int max = 4294967295\nunsigned long max = 4294967295<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">#include&lt;stdio.h&gt;\n\n\/* determine ranges of types *\/\nmain() {\n    \/* signed types *\/\n    printf(\"signed char min = %d\\n\",\n                    -(char)((unsigned char)~0 &gt;&gt; 1));\n    printf(\"signed char max = %d\\n\",\n                    (char)((unsigned char)~0 &gt;&gt; 1));\n    printf(\"signed short min = %d\\n\",\n                    -(short)((unsigned short)~0 &gt;&gt; 1));\n    printf(\"signed short max = %d\\n\",\n                    (short)((unsigned short)~0 &gt;&gt; 1));\n    printf(\"signed int min = %d\\n\",\n                    -(int)((unsigned int)~0 &gt;&gt; 1));\n    printf(\"signed int max = %d\\n\",\n                    (int)((unsigned int)~0 &gt;&gt; 1));\n    printf(\"signed long min = %d\\n\",\n                    -(long)((unsigned long)~0 &gt;&gt; 1));\n    printf(\"signed long max =  %d\\n\",\n                    (long)((unsigned long)~0 &gt;&gt; 1));\n\n    \/* unsigned types *\/\n    printf(\"unsigned char max = %u\\n\", \n                    (unsigned char)~0);\n    printf(\"unsigned short max = %u\\n\",\n                    (unsigned short)~0);\n    printf(\"unsigned int max = %u\\n\",\n                    (unsigned int)~0);\n    printf(\"unsigned long max = %u\\n\",\n                    (unsigned long)~0);\n}<\/code><\/pre>\n\n\n\n<p>Output Result:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">signed char min = -127\nsigned char max = 127\nsigned short min = -32767\nsigned short max = 32767\nsigned int min = -2147483647\nsigned int max = 2147483647\nsigned long min = -2147483647\nsigned long max =  2147483647\nunsigned char max = 255\nunsigned short max = 65535\nunsigned int max = 4294967295\nunsigned long max = 4294967295<\/code><\/pre>\n\n\n\n<p>Exercise 2-2. Write a loop equivalent to the <code>for<\/code> loop above without using <code>&amp;&amp;<\/code> or <code>||<\/code>.<\/p>\n\n\n\n<p>Original for loop code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">for(i=0; i&lt;lim-1 &amp;&amp; (c=getchar()) != '\\n' &amp;&amp; c != EOF; ++i)\n  s[i] = c;<\/code><\/pre>\n\n\n\n<p>Modified code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">#include&lt;stdio.h&gt;\n\n\/*\n  for(i=0; i&lt;lim-1 &amp;&amp; (c=getchar()) != '\\n' &amp;&amp; c != EOF; ++i)\n    s[i] = c;\n*\/\n\nenum loop {NO, YES};\nenum loop okloop = YES;\n#define MAXLINE 80\n\nmain(){\n    int c, i = 0, s[MAXLINE];\n    int lim = MAXLINE;\n    while (okloop == YES){\n        if (i &gt;= lim-1){\n            okloop = NO;\n        } else if ((c = getchar()) != '\\n'){\n            okloop = NO;\n        } else if (c != EOF){\n            okloop = NO;\n        } else {\n            s[i] = c;\n            ++i;\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<p>Exercise 2-3. Write the function <code>htoi(s)<\/code> , which converts a string of hexadecimal digits (including an optional <code>0x<\/code> or <code>0X<\/code>) into its equivalent integer value. The allowable digits are <code>0<\/code> through <code>9<\/code>, a through <code>f<\/code>, and <code>A<\/code> through <code>F<\/code> .<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">#include&lt;stdio.h&gt;\n\n#define MAXLINE 100\n#define YES 1\n#define NO  0\n\nint getline(char line[], int maxline);\nint htoi(char s[]);\n\nmain(){\n    int value;\n    char line[MAXLINE];\n    getline(line, MAXLINE);\n    value = htoi(line);\n\n    printf(\"The value of %s is %d \\n\", line, value);\n}\n\nint getline(char s[], int lim){\n    int c, i;\n    for (i = 0; i &lt; lim-1 &amp;&amp; ((c = getchar()) != EOF) &amp;&amp; c != '\\n'; ++i){\n        s[i] = c;\n    }\n    if (c == '\\n'){\n        s[i] = c;\n        ++i;\n    }\n    s[i] = '\\0';\n    return i;\n}\n\n\/* htoi: convert hexadecimal string's to integer*\/\nint htoi(char s[]){\n    int hexdigit, i, inhex, n;\n\n    i = 0;\n    if (s[i] == '0'){       \/* skip optionel 0x or 0X*\/\n        ++i;\n        if (s[i] == 'x' || s[i] == 'X'){\n            ++i;\n        }\n    }\n    n = 0;                  \/* integer value to be returned    *\/\n    inhex = YES;            \/* assume valid hexedecimal digit  *\/\n    for ( ; inhex == YES; ++i){\n        if (s[i] &gt;= '0' &amp;&amp; s[i] &lt;= '9'){\n            hexdigit = s[i] - '0';\n        } else if (s[i] &gt;= 'a' &amp;&amp; s[i] &lt;= 'f'){\n            hexdigit = s[i] - 'a' + 10;\n        } else if (s[i] &gt;= 'A' &amp;&amp; s[i] &lt;= 'F'){\n            hexdigit = s[i] - 'A' + 10;\n        } else {\n            inhex = NO;     \/* not a valid hexadecimal digit    *\/\n        }\n        if (inhex == YES){\n            n = 16 * n + hexdigit;\n        }\n    }\n    return n;\n}<\/code><\/pre>\n\n\n\n<p>For example to convert <strong>0XAF<\/strong>.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>We strip off 0X.<\/li>\n\n\n\n<li>For A, we get the value hexdigit = 10<\/li>\n\n\n\n<li>n = 16 * 0 + 10 = 10<\/li>\n\n\n\n<li><strong>We gather F, we store hexdigit = \u2018F\u2019 &#8211; \u2018A\u2019 + 10;<\/strong>= 70 &#8211; 65 + 10; (70 is ascii value for F, 65 is ascii value for A) = 15<\/li>\n\n\n\n<li>n = 16 <em>n + hexdigit = 16<\/em> 10 + 15 = 160 + 15 = 175<\/li>\n<\/ol>\n\n\n\n<p>Exercise 2-4. Write an alternate version of squeeze(s1,s2) that deletes each character in the string s1 that matches any character in the string s2 .<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">#include&lt;stdio.h&gt;\n#define MAXLINE 1000\n\nint mgetline(char line[], int maxline);\nvoid squeeze(char s1[], char s2[]);\n\nmain(){\n    char s1[MAXLINE], s2[MAXLINE];\n    putchar('s');\n    putchar('1');\n    mgetline(s1, MAXLINE);\n\n    putchar('s');\n    putchar('2');\n    mgetline(s2, MAXLINE);\n\n    squeeze(s1, s2);\n\n    printf(\"%s\",s1);\n\n    return 0;\n\n}\n\nint mgetline(char s[], int lim){\n    int i, c;\n\n    for (i = 0; 1 &lt; lim-1 &amp;&amp; (c = getchar()) != EOF &amp;&amp; c != '\\n'; ++i){\n        s[i] = c;\n    }\n    if (c == '\\n'){\n        s[i++] = c;\n    }\n    s[i] = '\\0';\n}\n\nvoid squeeze(char s1[],char s2[]){\n    int i, j, k;\n    k = 0;\n\n    for (i = 0; s1[i] != '\\0'; ++i){\n        for (j = 0; (s1[i] != s2[j]) &amp;&amp; s2[j] != '\\0'; ++j)\n            ;\n        if (s2[j] == '\\0'){\n            s1[k++] = s1[i];\n        }\n    }\n    s1[k] = '\\0';\n}<\/code><\/pre>\n\n\n\n<p><strong>Explanation:<\/strong><\/p>\n\n\n\n<p>Let\u2019s take the two inputs strings as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">s1: Hello,World\n\ns2: ol<\/code><\/pre>\n\n\n\n<p>Our desired output is:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">He,Wrd<\/code><\/pre>\n\n\n\n<p>This has removed the characters o and l from the first string. The way squeeze works is, it take each character from the first string and if there is no match found, stores it with a new index k. If there is a match found in s2, it simply skips it. The way it skips is realized by the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">for(j=0; (s1[i]!=s2[j]) &amp;&amp; s2[j]!='\\0' ;++j)\n    ;\nif(s2[j]=='\\0')\n    s1[k++] = s1[i];<\/code><\/pre>\n\n\n\n<p>When the match is found s1[i] == s2[j] so our first for loop will end. The second if condtion will fail too as s2 is not iterated till the end, so we do not place the character in s1[k++] and we have successfully skipped it.<\/p>\n\n\n\n<p>Exercise 2-5: Write the function any<code>(s1,s2)<\/code> , which returns the first location in the string <code>s1<\/code> where any character from the string <code>s2<\/code> occurs, or <code>-1<\/code> if <code>s1<\/code> contains no characters from <code>s2<\/code> . (The standard library function <code>strpbrk<\/code> does the same job but returns a pointer to the location.)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"c\" class=\"language-c\">#include&lt;stdio.h&gt;\n#define MAXLINE 1000\n\nint getline(char line[], int maxline);\nint any(char s1[], char s2[]);\n\nmain(){\n    char s1[MAXLINE], s2[MAXLINE];\n    int val;\n\n    getline(s1, MAXLINE);\n\n    getline(s2, MAXLINE);\n\n    val = any(s1, s2);\n    printf(\"%d\", val);\n    return 0;\n}\n\nint getline(char s[], int lim){\n    int i, c;\n    for (i = 0; i &lt; lim-1 &amp;&amp; (c = getchar()) != EOF &amp;&amp; c != '\\n'; ++i){\n        s[i] = c;\n    }\n    if (c == '\\n'){\n        s[i++] = c;\n    }\n    s[i] = '\\0';\n}\n\nint any(char s1[], char s2[]){\n    int i, j;\n    for (i = 0; s1[i] != '\\0'; ++i){\n        \/\/ iterate through s2 while trying to find matching character from s1\n        for (j = 0; (s1[i] != s2[j]) &amp;&amp; s2[j] != '\\0'; ++j)\n            ;   \/\/continue\n        if (s2[j] != '\\0' &amp;&amp; s2[j] != '\\n'){\n            return i;\n        }\n\n    }\n    return -1;\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Exercise 2-1. Write a program to determine the ranges o &hellip; <a href=\"https:\/\/blog.liuyingjie.com.cn\/?p=533\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">K&#038;R2 solutions: Chapter 2 &#8211; Types, Operators and Expressions<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[8],"tags":[],"class_list":["post-533","post","type-post","status-publish","format-standard","hentry","category-c"],"_links":{"self":[{"href":"https:\/\/blog.liuyingjie.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.liuyingjie.com.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.liuyingjie.com.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.liuyingjie.com.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.liuyingjie.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=533"}],"version-history":[{"count":32,"href":"https:\/\/blog.liuyingjie.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/533\/revisions"}],"predecessor-version":[{"id":979,"href":"https:\/\/blog.liuyingjie.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/533\/revisions\/979"}],"wp:attachment":[{"href":"https:\/\/blog.liuyingjie.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.liuyingjie.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.liuyingjie.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}