summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhineng Li <[email protected]>2026-01-10 16:37:39 +0800
committerZhineng Li <[email protected]>2026-01-10 16:37:39 +0800
commit49891f6bce29843f503b437c84d83cb787ecfa87 (patch)
tree50bd44422a907b869a6d4839df436f37a35be36d
downloadc-knr-exercises-49891f6bce29843f503b437c84d83cb787ecfa87.tar.gz
c-knr-exercises-49891f6bce29843f503b437c84d83cb787ecfa87.zip
first commit
-rw-r--r--.gitignore1
-rw-r--r--README.md2
-rw-r--r--ch01/ex01-hello.c6
-rw-r--r--ch01/ex02-exp.c6
-rw-r--r--ch01/ex03-temp.c21
-rw-r--r--ch01/ex04-temp.c21
-rw-r--r--ch01/ex05-temp.c11
-rw-r--r--ch01/ex06-eof.c6
-rw-r--r--ch01/ex07-eof.c6
-rw-r--r--ch01/ex08-count.c22
-rw-r--r--ch01/ex09-copy.c21
-rw-r--r--ch01/ex10-replace.c26
-rw-r--r--ch01/ex11-wc.c35
-rw-r--r--ch01/ex12-print.c23
-rw-r--r--ch01/ex13-histogram.c52
15 files changed, 259 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cba7efc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+a.out
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9ec5d3b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+Implementations of the exercises from The C Programming Language (2nd
+Edition) by Kernighan and Ritchie.
diff --git a/ch01/ex01-hello.c b/ch01/ex01-hello.c
new file mode 100644
index 0000000..53f4080
--- /dev/null
+++ b/ch01/ex01-hello.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("hello, world\n");
+}
diff --git a/ch01/ex02-exp.c b/ch01/ex02-exp.c
new file mode 100644
index 0000000..dcc46dd
--- /dev/null
+++ b/ch01/ex02-exp.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("hello, world\c");
+}
diff --git a/ch01/ex03-temp.c b/ch01/ex03-temp.c
new file mode 100644
index 0000000..b52e241
--- /dev/null
+++ b/ch01/ex03-temp.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+/* print Fahrenheit-Celsius table */
+int main()
+{
+ float fahr, celsius;
+ int lower, upper, step;
+
+ lower = 0;
+ upper = 300;
+ step = 20;
+
+ printf("%3s %6s\n", "F", "C");
+
+ fahr = lower;
+ while (fahr <= upper) {
+ celsius = (5.0/9.0) * (fahr-32.0);
+ printf("%3.0f %6.1f\n", fahr, celsius);
+ fahr = fahr + step;
+ }
+}
diff --git a/ch01/ex04-temp.c b/ch01/ex04-temp.c
new file mode 100644
index 0000000..f78a191
--- /dev/null
+++ b/ch01/ex04-temp.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+/* print Celsius-Fahrenheit table */
+int main()
+{
+ float celsius, fahr;
+ int lower, upper, step;
+
+ lower = 0;
+ upper = 300;
+ step = 20;
+
+ printf("%3s %6s\n", "C", "F");
+
+ celsius = lower;
+ while (celsius <= upper) {
+ fahr = celsius / (5.0/9.0) + 32.0;
+ printf("%3.0f %6.0f\n", celsius, fahr);
+ celsius = celsius + step;
+ }
+}
diff --git a/ch01/ex05-temp.c b/ch01/ex05-temp.c
new file mode 100644
index 0000000..6af87c6
--- /dev/null
+++ b/ch01/ex05-temp.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+/* print Fahrenheit-Celsius table, in reverse order */
+int main()
+{
+ int fahr;
+
+ for (fahr = 300; fahr >= 0; fahr = fahr - 20) {
+ printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
+ }
+}
diff --git a/ch01/ex06-eof.c b/ch01/ex06-eof.c
new file mode 100644
index 0000000..bd8fae5
--- /dev/null
+++ b/ch01/ex06-eof.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("%d\n", getchar() != EOF);
+}
diff --git a/ch01/ex07-eof.c b/ch01/ex07-eof.c
new file mode 100644
index 0000000..f91bb75
--- /dev/null
+++ b/ch01/ex07-eof.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("%d\n", EOF);
+}
diff --git a/ch01/ex08-count.c b/ch01/ex08-count.c
new file mode 100644
index 0000000..c5052e6
--- /dev/null
+++ b/ch01/ex08-count.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+/* count blanks, tabs, and newlines in input */
+int main()
+{
+ int c;
+ int ns, nt, nl;
+
+ ns = 0;
+ nt = 0;
+ nl = 0;
+
+ while ((c=getchar()) != EOF) {
+ if (c == ' ')
+ ++ns;
+ if (c == '\t')
+ ++nt;
+ if (c == '\n')
+ ++nl;
+ }
+ printf("%d %d %d\n", ns, nt, nl);
+}
diff --git a/ch01/ex09-copy.c b/ch01/ex09-copy.c
new file mode 100644
index 0000000..2303b83
--- /dev/null
+++ b/ch01/ex09-copy.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+/* merge consecutive blanks */
+int main()
+{
+ int c, b;
+
+ b = 0;
+ while ((c = getchar()) != EOF) {
+ if (c != ' ') {
+ putchar(c);
+ b = 0;
+ }
+
+ if (c == ' ') {
+ if (b == 0)
+ putchar(c);
+ b = 1;
+ }
+ }
+}
diff --git a/ch01/ex10-replace.c b/ch01/ex10-replace.c
new file mode 100644
index 0000000..b7ec4a5
--- /dev/null
+++ b/ch01/ex10-replace.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+/* replace each tab by \t, each backspace by \b, and each backslash by \\ */
+int main()
+{
+ int c;
+
+ while ((c = getchar()) != EOF) {
+ if (c == '\t') {
+ putchar('\\');
+ putchar('t');
+ }
+ if (c == '\b') {
+ putchar('\\');
+ putchar('b');
+ }
+ if (c == '\\') {
+ putchar('\\');
+ putchar('\\');
+ }
+ if (c != '\t')
+ if (c != '\b')
+ if (c != '\\')
+ putchar(c);
+ }
+}
diff --git a/ch01/ex11-wc.c b/ch01/ex11-wc.c
new file mode 100644
index 0000000..e2ec1d8
--- /dev/null
+++ b/ch01/ex11-wc.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+
+#define IN 1 /* inside a word */
+#define OUT 0 /* outside a word */
+
+/* count lines, words, and characters in input
+ *
+ * I would focus on testing the state transitions, since character and
+ * line counting are straightforward. The character count increments for
+ * every character that is not EOF, and the line count increments whenever
+ * a newline is encountered. Word counting is more complex because it
+ * depends on correctly detecting boundaries. I would include test cases
+ * with varying numbers of spaces, tabs, and newlines to verify that word
+ * boundaries are handled correctly, since those inputs are the most likely
+ * to reveal bugs.
+ */
+int main()
+{
+ int c, nl, nw, nc, state;
+
+ state = OUT;
+ nl = nw = nc = 0;
+ while ((c = getchar()) != EOF) {
+ nc++;
+ if (c == '\n')
+ ++nl;
+ if (c == ' ' || c == '\n' || c == '\t')
+ state = OUT;
+ else if (state == OUT) {
+ state = IN;
+ ++nw;
+ }
+ }
+ printf("%d %d %d\n", nl, nw, nc);
+}
diff --git a/ch01/ex12-print.c b/ch01/ex12-print.c
new file mode 100644
index 0000000..91aafa2
--- /dev/null
+++ b/ch01/ex12-print.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+#define IN 1 /* inside a word */
+#define OUT 0 /* outside a word */
+
+/* print one word per line from the input */
+int main()
+{
+ int c, state;
+
+ state = OUT;
+ while ((c = getchar()) != EOF) {
+ if (c == ' ' || c == '\n' || c == '\t') {
+ if (state == IN)
+ putchar('\n');
+ state = OUT;
+ } else if (state == OUT)
+ state = IN;
+ if (state == IN)
+ putchar(c);
+ }
+ putchar('\n');
+}
diff --git a/ch01/ex13-histogram.c b/ch01/ex13-histogram.c
new file mode 100644
index 0000000..14002a5
--- /dev/null
+++ b/ch01/ex13-histogram.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+
+#define IN 1 /* inside a word */
+#define OUT 0 /* outside a word */
+
+/* print a histogram of word lengths */
+int main()
+{
+ int c, i, j, nc, state;
+ int ndigit[10];
+
+ for (i = 0; i < 10; ++i)
+ ndigit[i] = 0;
+
+ nc = 0;
+ state = OUT;
+ while ((c = getchar()) != EOF) {
+ if (c == ' ' || c == '\n' || c == '\t') {
+ if (state == IN) {
+ i = nc - 1;
+ if (i > 9)
+ i = 9;
+ ++ndigit[i];
+ nc = 0;
+ }
+ state = OUT;
+ } else if (state == OUT) {
+ state = IN;
+ }
+
+ if (state == IN)
+ ++nc;
+ }
+
+ if (state == IN) {
+ i = nc - 1;
+ if (i > 9)
+ i = 9;
+ ++ndigit[i];
+ nc = 0;
+ }
+
+ for (i = 0; i < 10; ++i) {
+ if (i == 9)
+ printf(" >9: ");
+ else
+ printf(" %2d: ", i + 1);
+ for (j = 0; j < ndigit[i]; ++j)
+ putchar('#');
+ putchar('\n');
+ }
+}