History of the C language
=========================


C (/ˈsiː/, as in the letter c) is a general-purpose, imperative computer
programming language, supporting structured programming, lexical variable
scope and recursion, while a static type system prevents many unintended
operations. By design, C provides constructs that map efficiently to typical
machine instructions, and therefore it has found lasting use in applications
that had formerly been coded in assembly language, including operating
systems, as well as various application software for computers ranging from
supercomputers to embedded systems.

( from Wikipedia https://en.wikipedia.org/wiki/C_(programming_language) ) 


- Origins:

          Assembly -> BCPL -> B -> C           -> D
                                       -> C++
                                               -> Java
                                               -> C#


- Timeline:

    - Ken Thompson develops B (a simplified BCPL)           1969

    - Ken Thompson, Dennis Ritchie and others work on UNIX  1969-

    - Dennis Ritchie develops C        1972

    - UNIX kerner is rewritten in C    1972-73

    - Johnson's Portable C Compiler    1977

    - Brian Kernighan & Dennis Ritchie: The C Programming Language book 1978
             K&R C

    - ANSI C standard (C90)            1989    (32 keywords)

    - C99 standard                     1999    (+5 keywords)

    - C11 standard                     2011    (+7 keywords)






Compiling, linking, executing
=============================


  preprocessing   compiling         linking   executing

header      source      object       library

  a.h
  b.h   ->    b.c    ->   b.o  ---------|
                                        ----->    a.out (b.exe)
  e.h                                   |            |
  f.h   ->    d.c    ->   d.o  ---------|            |runtime
                                        |            |
  g.h   ->    g.c    ->   g.o           |            |
  h.h   ->    h.c    ->   h.o    ->   h.a  (h.lib)   |
                                       archive       |
  i.h   ->    i.c    ->   i.o                        |
  j.h   ->    j.c    ->   j.o    ->   j.so (j.dll) --|
                                      shared object





$ cat hello.c

#include <stdio.h>

int main()
{
  printf( "hello world\n" );
  return 0;   /* not strictly necessary since C99 */
}



#// compile + link
$ gcc  hello.c

#// execute
$ ./a.out


// compile + link + set warnings on
#$ gcc -ansi -pedantic -Wall -W hello.c


#// c11 mode
$ gcc -std=c11 -ansi -pedantic -Wall -W hello.c


#// set output name to a.exe
$ gcc -std=c11 -ansi -pedantic -Wall -W hello.c -o a.exe


#// compile only
$ gcc -c  hello.c
$ ls
hello.o


#// will call the linker 
$ gcc hello.o


#// calls the compiler for all sources then calls the linker
$ gcc a.c b.c d.o e.a f.so





/*
 *  BAD VERSION !!!
 *
 *  Missing header
 *
 */

// #include <stdio.h>

int main()
{
  printf("hello world\n");
  return 0;
}


$ gcc -ansi -pedantic -W -Wall -std=c11 hello2.c -c
hello2.c: In function ‘main’:
hello2.c:6:3: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
   printf("hello world\n");
   ^
hello2.c:6:3: warning: incompatible implicit declaration of built-in function ‘printf’








Fahrenheit to Celsius: The Bad, the Ugly and the Good
=====================================================




/*
 *  BAD VERSION !!!
 *
 *  Convert Fahrenheit to Celsius
 *  between -100F and +400F  by 25F  
 */

#include <stdio.h>

int main()
{
  int fahr;

  for ( fahr = -100; fahr <= 400; fahr += 25 )
  {
    printf( "Fahr = %d\t,Cels = %d\n", fahr, 5/9*(fahr-32) );
  }

  return 0;
}



$ gcc -ansi -pedantic -W -Wall -std=c11 fahrenheit.c -o fahrenheit

$ ./fahrenheit
Fahr = -100	,Cels = 0
Fahr = -75	,Cels = 0
Fahr = -50	,Cels = 0
Fahr = -25	,Cels = 0
Fahr = 0	,Cels = 0
Fahr = 25	,Cels = 0
Fahr = 50	,Cels = 0
Fahr = 75	,Cels = 0
Fahr = 100	,Cels = 0
Fahr = 125	,Cels = 0
Fahr = 150	,Cels = 0
Fahr = 175	,Cels = 0
Fahr = 200	,Cels = 0
Fahr = 225	,Cels = 0
Fahr = 250	,Cels = 0
Fahr = 275	,Cels = 0
Fahr = 300	,Cels = 0
Fahr = 325	,Cels = 0
Fahr = 350	,Cels = 0
Fahr = 375	,Cels = 0
Fahr = 400	,Cels = 0





/*
 *  BAD VERSION !!!
 *
 *  Convert Fahrenheit to Celsius
 *  between -100F and +400F  by 25F  
 */

#include <stdio.h>

int main()
{
  int fahr;

  for ( fahr = -100; fahr <= 400; fahr += 25 )
  {
    printf( "Fahr = %d\t,Cels = %d\n", fahr, 5./9.*(fahr-32) );
  }

  return 0;
}




$ gcc -ansi -pedantic -W -Wall -std=c11 fahrenheit.c -o fahrenheit
fahrenheit.c: In function ‘main’:
fahrenheit.c:17:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘double’ [-Wformat=]
     printf( "Fahr = %d,\tCels = %d\n", fahr, 5./9.*(fahr-32) );
     ^

$ ./fahrenheit
Fahr = -100,	Cels = 913552376
Fahr = -75,	Cels = -722576928
Fahr = -50,	Cels = -722576928
Fahr = -25,	Cels = -722576928
Fahr = 0,	Cels = -722576928
Fahr = 25,	Cels = -722576928
Fahr = 50,	Cels = -722576928
Fahr = 75,	Cels = -722576928
Fahr = 100,	Cels = -722576928
Fahr = 125,	Cels = -722576928
Fahr = 150,	Cels = -722576928
Fahr = 175,	Cels = -722576928
Fahr = 200,	Cels = -722576928
Fahr = 225,	Cels = -722576928
Fahr = 250,	Cels = -722576928
Fahr = 275,	Cels = -722576928
Fahr = 300,	Cels = -722576928
Fahr = 325,	Cels = -722576928
Fahr = 350,	Cels = -722576928
Fahr = 375,	Cels = -722576928
Fahr = 400,	Cels = -722576928






/*
 *  UGLY VERSION
 *
 *  Convert Fahrenheit to Celsius
 *  between -100F and +400F  by 25F  
 */

#include <stdio.h>

int main()
{
  int fahr;

  for ( fahr = -100; fahr <= 400; fahr += 25 )
  {
    printf( "Fahr = %d,\tCels = %f\n", fahr, 5./9.*(fahr-32) );
  }

  return 0;
}





$ gcc -ansi -pedantic -W -Wall -std=c11 fahrenheit.c -o fahrenheit

$ ./fahrenheit
Fahr = -100,	Cels = -73.333333
Fahr = -75,	Cels = -59.444444
Fahr = -50,	Cels = -45.555556
Fahr = -25,	Cels = -31.666667
Fahr = 0,	Cels = -17.777778
Fahr = 25,	Cels = -3.888889
Fahr = 50,	Cels = 10.000000
Fahr = 75,	Cels = 23.888889
Fahr = 100,	Cels = 37.777778
Fahr = 125,	Cels = 51.666667
Fahr = 150,	Cels = 65.555556
Fahr = 175,	Cels = 79.444444
Fahr = 200,	Cels = 93.333333
Fahr = 225,	Cels = 107.222222
Fahr = 250,	Cels = 121.111111
Fahr = 275,	Cels = 135.000000
Fahr = 300,	Cels = 148.888889
Fahr = 325,	Cels = 162.777778
Fahr = 350,	Cels = 176.666667
Fahr = 375,	Cels = 190.555556
Fahr = 400,	Cels = 204.444444





/*
 *  OK
 *
 *  Convert Fahrenheit to Celsius
 *  between -100F and +400F  by 25F  
 */

#include <stdio.h>


double fahr2cels( double f)
{./
  return 5./9. * (f-32);
}

int main()
{
  int fahr;

  for ( fahr = -100; fahr <= 400; fahr += 25 )
  {
    printf( "Fahr = %4d,\tCels = %7.2f\n", fahr, fahr2cels(fahr) );
  }

  return 0;
}



$ gcc -ansi -pedantic -W -Wall -std=c11 fahrenheit.c -o fahrenheit

$ ./fahrenheit
Fahr = -100,	Cels =  -73.33
Fahr =  -75,	Cels =  -59.44
Fahr =  -50,	Cels =  -45.56
Fahr =  -25,	Cels =  -31.67
Fahr =    0,	Cels =  -17.78
Fahr =   25,	Cels =   -3.89
Fahr =   50,	Cels =   10.00
Fahr =   75,	Cels =   23.89
Fahr =  100,	Cels =   37.78
Fahr =  125,	Cels =   51.67
Fahr =  150,	Cels =   65.56
Fahr =  175,	Cels =   79.44
Fahr =  200,	Cels =   93.33
Fahr =  225,	Cels =  107.22
Fahr =  250,	Cels =  121.11
Fahr =  275,	Cels =  135.00
Fahr =  300,	Cels =  148.89
Fahr =  325,	Cels =  162.78
Fahr =  350,	Cels =  176.67
Fahr =  375,	Cels =  190.56
Fahr =  400,	Cels =  204.44






/*
 *  OK, with #define
 *
 *  Convert Fahrenheit to Celsius
 *  between -100F and +400F  by 25F  
 */

#include <stdio.h>

#define LOWER -100
#define UPPER  400
#define STEP    25

double fahr2cels( double f)
{
  return 5./9. * (f-32);
}

int main()
{
  int fahr;

  for ( fahr = LOWER; fahr <= UPPER; fahr += STEP )
  {
    printf( "Fahr = %4d,\tCels = %7.2f\n", fahr, fahr2cels(fahr) );
  }

  return 0;
}




/*
 *  OK, with const
 *
 *  Convert Fahrenheit to Celsius
 *  between -100F and +400F  by 25F  
 */

#include <stdio.h>

const int lower = -100;
const int upper =  400;
const int step  =   25;

double fahr2cels( double f)
{
  return 5./9. * (f-32);
}

int main()
{
  int fahr;

  for ( fahr = lower; fahr <= upper; fahr += step )
  {
    printf( "Fahr = %4d,\tCels = %7.2f\n", fahr, fahr2cels(fahr) );
  }

  return 0;
}





Homework:


1. Create a program printing your name. Compile, link, run.
2. Separate the program to 2 sources: one return the name, other prints
     Hints: - use char *my_name() as a function prototype.
            - use "%s" as a format string for printf