Some solutions to k&r chapter 2

master
Tibor Bizjak 2023-06-02 13:12:29 +02:00
parent b83bed8fd1
commit 5304a59ba7
7 changed files with 244 additions and 0 deletions

View File

@ -0,0 +1,85 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <limits.h>
#include <float.h>
#define BREAK_W 80
#define INDENT "\t"
#define PRINT_BITS(T, BITS) \
printf(#T"\n"); \
printf(INDENT"bits : %d\n", BITS)
#define PRINT_LIMS(T, F, BITS, MIN, MAX, UMAX) \
PRINT_BITS(T, BITS); \
printf(INDENT"signed : %"#F"d %"#F"d\n", MIN, MAX); \
printf(INDENT"unsigned : %"#F"u\n\n", UMAX)
#define PRINT_FLIMS(T, F, BITS, MIN, MAX) \
PRINT_BITS(T, BITS); \
printf(INDENT"min : %.0"#F"f\n", MIN); \
printf(INDENT"max : %.0"#F"f\n\n", MAX)
#define LIMITS(T, F) \
T T##lim; \
unsigned T u##T##lim = 0; \
b = 1; \
for (T##lim = 1; T##lim > 0; T##lim *= 2) ++b; \
PRINT_LIMS(T, F, b, T##lim--, T##lim, --u##T##lim)
#define FLIMITS(T, F) \
T T##max; \
T T##min; \
b = 2; \
for (T##max = 1; !isinf(T##max * 2); T##max *= 2) ++b; \
for (T##min = -1; !isinf(T##min * 2); T##min *= 2) ++b; \
PRINT_FLIMS(T, F, b, T##min, T##max)
#define HLIMITS(T, F) \
int T##bits = ceil(log2(U##T##_MAX)); \
PRINT_LIMS(T, F, T##bits, T##_MIN, T##_MAX, U##T##_MAX)
#define HFLIMITS(T, F) \
int T##bits = ceil(log2(T##_MAX)) * 2; \
PRINT_FLIMS(T, F, T##bits, T##_MIN, T##_MAX)
void print_break(char s[]);
/* print type size information, first by computation, then from headers */
int main()
{
int b;
print_break("By Computation");
LIMITS(char, );
LIMITS(short, );
LIMITS(int, );
LIMITS(long, l);
FLIMITS(float, );
FLIMITS(double, l);
print_break("From Headers");
HLIMITS(CHAR, );
HLIMITS(SHRT, );
HLIMITS(INT, );
HLIMITS(LONG, l);
HFLIMITS(FLT, );
HFLIMITS(DBL, l);
}
/* print string 's' padded with '-' on both sides to width 'BREAK_W' */
void print_break(char s[])
{
int i, len = BREAK_W - strlen(s) - 2;
for (i = 0; i < len; i += 2)
putchar('-');
printf(" %s ", s);
for (i = 1; i < len; i += 2)
putchar('-');
putchar('\n');
}

View File

@ -0,0 +1,13 @@
#include <stdio.h>
#define LIM 100
int main()
{
int c, i;
char s[LIM];
for (i=0; (i < LIM-1) ? ((c=getchar() != '\n') ? c != EOF : 0) : 0; ++i)
s[i] = c;
return 0;
}

View File

@ -0,0 +1,46 @@
#include <stdio.h>
int htoi(int *i, char s[]);
/* converts first argument to decimal from hex */
int main(int argc, char *argv[])
{
if (argc < 2) { // no argument
printf("error : expected hexadecimal argument\n");
return 1;
}
int n, i = 0;
n = htoi(&i, argv[1]);
if (argv[1][i] != '\0') { // invalid argument
printf("%s\n", argv[1]);
for (; i > 0; --i)
putchar(' ');
printf("^\n");
printf("error : invalid character in hexadecimal constant\n");
return 1;
}
printf("%d\n", n);
return 0;
}
/* htoi: converts hexadecimal constant 's' to decimal and returns the result
* reads 's' from 'i' to end */
int htoi(int *i, char s[])
{
int n = 0;
if (s[*i] == '0' && (s[*i+1] == 'x' || s[*i+1] == 'X'))
*i += 2;
for (; s[*i] != '\0'; ++*i) {
#define X(a, b, base) if (s[*i] >= a && s[*i] <= b) n = 16 * n + base + s[*i] - a; else
X('0', '9', 0)
X('a', 'f', 10)
X('A', 'F', 10)
#undef X
break;
}
return n;
}

View File

@ -0,0 +1,32 @@
#include <stdio.h>
void squeeze(char s[], char cs[]);
/* deletes all characters from second arg from first arg */
int main(int argc, char *argv[])
{
if (argc == 1) {
printf("error : expected string to squeeze\n");
return 1;
}
if (argc > 2)
squeeze(argv[1], argv[2]);
printf("%s\n", argv[1]);
return 0;
}
/* squeeze : deletes all characters from 'cs' from 's' */
void squeeze(char s[], char cs[])
{
int i, j;
int ci, cf;
for (i = j = 0; s[i] != '\0'; i++) {
for (ci = 0; cs[ci] != '\0' && (cf = (cs[ci] != s[i])); ci++)
;
if (cf)
s[j++] = s[i];
}
s[j] = '\0';
}

View File

@ -0,0 +1,35 @@
#include <stdio.h>
int any(char s1[], char s2[]);
/* points out the place shere any char from snd arg occurs in fst arg */
int main(int argc, char *argv[])
{
if (argc <= 2) {
printf("error : expected two arguments\n");
return 1;
}
int i = any(argv[1], argv[2]);
if (i < 0)
printf("No occurence\n");
else {
printf("%s\n", argv[1]);
printf("%*s^\n", i, "");
}
return 0;
}
/* any: returns first location in string 's' where char from 'cs' occurs.
* returns -1 if none occur */
int any(char s[], char cs[])
{
int i, j;
for (i = 0; s[i] != '\0'; i++)
for (j = 0; cs[j] != '\0'; j++)
if (s[i] == cs[j])
return i;
return -1;
}

View File

@ -0,0 +1,11 @@
#include "bitwise.h"
#define F(n) getbits(n, 4, 3)
int getbits(unsigned x, int p, int n)
{
printf("%d\n", x);
return (x >> (p+1-n)) & ~(~0 << n);
}
MAIN

View File

@ -0,0 +1,22 @@
#ifndef BITWISE_H
#define BITWISE_H
#include <stdio.h>
unsigned int int_of_bin(char bs[]);
void print_bin(unsigned int n);
/* standard main, applies function F to binary
* input and prints result (in binary) */
#define MAIN \
int main(int argc, char *argv[]) \
{ \
if (argc < 0) { \
printf("error : expected binary string argument\n"); \
return 1; \
} \
print_bin(F(int_of_bin(argv[1]))); \
putchar('\n'); \
} \
#endif // BITWISE_H