C programming Language – Code snippets
C Programming Language, 2nd Edition
Compiling and running the sample codes using gcc :
This shell example compiles one saved C source file into an executable named sample, then runs it from the current directory. It is a workflow illustration, not a guarantee that every historical example below compiles unchanged with a modern compiler; inspect the individual caveats first.
gcc sample.c -o sample
./sample
Chapter 4 - Functions and Program structure
1. A conditional in the C preprocessor
This example selects a macro definition during preprocessing using conditional directives, then prints the selected value at runtime. SYSTEM is set to a value outside the explicit branches, so the later not-defined check supplies the fallback HDR. The selection occurs before compilation, not through a runtime if statement.
#include<stdio.h>
#define SYSTEM 5
#if SYSTEM == 1
#define HDR 10
#elif SYSTEM == 2
#define HDR 20
#elif SYSTEM == 3
#define HDR 30
/*#else
#define HDR 0*/
#endif
#if !defined(HDR)
#define HDR 50
#endif
int main()
{
printf("HDR = %d \n", HDR);
return 0;
}
2. Macro definitions
These macros demonstrate expression substitution, a loop alias, stringification and token pasting. Parenthesizing expression arguments reduces precedence surprises, but a macro may evaluate an argument more than once. In this preserved sample, dprint passes an integer division result to a floating-point format, so that call has undefined behavior.
#include<stdio.h>
#define max(A,B) ((A)>(B) ? (A) : (B))
#define forever for(;;)
#define square(x) ((x)*(x))
#define dprint(expr) printf(#expr " = %g\n", expr)
#define paste(front, back) front ## back
int main()
{
char name[]="daniel";
int counter=0,x=4,y=2;
printf("Max=%d\n",max(8,9));
forever
{
printf(" %d ", counter);
if ( counter++ >= 10) break;
}
printf("\n");
printf("Square of 4 is %d\n",square(4));
dprint(x/y);
return 0;
}
3. Pattern matching
This line filter searches for a fixed substring with nested comparisons and prints lines containing it. strindex returns the first matching position or minus one. It demonstrates decomposing input, search and output into functions; the fixed buffers and custom getline identifier need modern portability review.
#include<stdio.h>
#define MAXLINE 1000
int getline(char line[], int max);
int strindex(char source[], char searchfor[]);
char pattern[]="dan";
int main()
{
char line[MAXLINE];
int found=0;
while(getline(line,MAXLINE)>0)
if(strindex(line,pattern) >= 0)
{
printf("%s",line);
found ++;
}
return found;
}
int getline(char s[], int lim)
{
int c, i;
i=0;
while(--lim > 0 && (c=getchar()) != EOF && c!='\n')
s[i++]=c;
if(c=='\n')
s[i++]=c;
s[i]='\0';
return i;
}
int strindex(char s[], char t[])
{
int i,j,k;
for(i=0; s[i]!='\0'; i++)
{
for(j=i, k=0; t[k]!='\0' && s[j]==t[k]; j++, k++);
if(k>0 && t[k] == '\0')
return i;
}
return -1;
}
4. Reverse polish calculator
This reverse Polish calculator tokenizes numbers and operators, stores operands on a stack and applies arithmetic when an operator arrives. Subtraction and division pop the right operand first, preserving operand order. Pushback supports token boundaries. Stack diagnostics illustrate error paths, but numeric and input handling remain intentionally limited.
/*reverse Polish calculator */
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MAXOP 100
#define NUMBER '0'
#define MAXVAL 100
#define BUFSIZE 100
int getch(void);
void ungetch(int);
int getop(char []);
void push(double);
double pop(void);
int sp = 0;
double val[MAXVAL];
char buf[BUFSIZE];
int bufp=0;
int main()
{
int type;
double op2;
char s[MAXOP];
while((type=getop(s)) != EOF)
{
switch(type)
{
case NUMBER: push(atof(s)); break;
case '+': push(pop() + pop()); break;
case '-': op2=pop(); push(pop() - op2); break;
case '*': push(pop() * pop()); break;
case '/':
op2=pop();
if(op2 != 0.0) push(pop()/op2);
else
printf("Error: zero divisor\n");
break;
case '\n': printf("\t%.8g\n", pop()); break;
default: printf("Error: unknown command %s\n", s); break;
}
}
return 0;
}
void push(double f)
{
if(sp < MAXVAL) val[sp++] = f;
else
printf("Error: stack full, can't push %g\n", f);
}
double pop(void)
{
if(sp > 0)
return val[--sp];
else
{
printf("Error: stack empty\n");
return 0.0;
}
}
int getop(char s[])
{
int i, c;
while((s[0] = c = getch()) == ' ' || c == '\t') ;
s[1] = '\0';
if(!isdigit(c) && c!= '.') return c;
i=0;
if(isdigit(c))
while(isdigit(s[++i] = c= getch())) ;
if ( c=='.')
while(isdigit(s[++i] = c = getch())) ;
s[i] = '\0';
if ( c!= EOF) ungetch(c);
return NUMBER;
}
int getch(void)
{
return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c)
{
if (bufp >= BUFSIZE) printf("ungetch: too many characters\n");
else
buf[bufp++]=c;
}
5. Quick sort
This quicksort selects a pivot, partitions smaller values before it and recursively sorts the two sides. A swap helper keeps element exchange separate from the recursive algorithm. It demonstrates divide-and-conquer on a fixed integer array; performance and recursion depth depend on partition quality and input.
#include<stdio.h>
void qsort(int v[], int left, int right);
int main()
{
int i, v[]={9,5,8,12,56,7,1,19,27,99,27,13,3};
for(i=0; i<13; i++) printf(" %d ",v[i]);
printf("\n");
qsort(v,0,12);
for(i=0; i<13; i++) printf(" %d ",v[i]);
printf("\n");
return 0;
}
void qsort(int v[], int left, int right)
{
int i, last;
void swap(int v[], int i, int j);
if(left >= right) return;
swap(v, left, (left + right)/2);
last = left;
for(i=left+1; i<=right; i++)
if(v[i] < v[left]) swap(v,++last, i);
swap(v, left, last);
qsort(v, left, last-1);
qsort(v, last+1, right);
}
void swap(int v[], int i, int j)
{
int temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
6. Rudimentary calculator
This running-total calculator reads a line, converts a decimal string with its own atof routine and adds it to an accumulated sum. The conversion separates sign, whole-number digits and fractional scale. It omits exponent notation and robust validation, and historical library-function names can conflict with current declarations.
#include<stdio.h>
#include<ctype.h>
#define MAXLINE 100
double atof(char s[]);
int getline(char line[], int max);
int main()
{
double sum, atof(char []);
char line[MAXLINE];
int getline(char line[], int max);
sum=0;
while(getline(line,MAXLINE) > 0)
printf("\t%g\n", sum+=atof(line));
return 0;
}
double atof(char s[])
{
double val, power;
int i, sign;
for (i=0; isspace(s[i]); i++);
sign=(s[i]=='-') ? -1: 1;
if(s[i]=='+' || s[i] == '-') i++;
for (val=0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
if(s[i] == '.') i++;
for(power=1.0; isdigit(s[i]); i++)
{
val = 10.0*val + (s[i] - '0');
power*=10;
}
return (sign*val/power);
}
int getline(char line[], int max)
{
int c,i;
for(i=0; i<max-1 && (c=getchar())!=EOF && c!='\n'; ++i)
line[i]=c;
if(c=='\n') {
line[i]=c;
++i;
}
line[i]='\0';
return i;
}
7. ASCII string to float conversion
This standalone decimal conversion walks past whitespace, records the sign, accumulates whole and fractional digits, and divides by the accumulated power of ten. It demonstrates parsing without calling the library conversion routine. It accepts only a limited grammar and does not report invalid suffixes or overflow.
#include<stdio.h>
#include<ctype.h>
int main()
{
double val, power;
int i, sign;
char s[]=" -23.590 ";
for (i=0; isspace(s[i]); i++);
sign=(s[i]=='-') ? -1: 1;
if(s[i]=='+' || s[i] == '-') i++;
for (val=0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
if(s[i] == '.') i++;
for(power=1.0; isdigit(s[i]); i++)
{
val = 10.0*val + (s[i] - '0');
power*=10;
}
printf("Value = %f\n", (sign*val/power));
return 1;
}
References -
https://www.amazon.com/Programming-Language-2nd-Brian-Kernighan/dp/0131103628#reader\_0131103628