C Language - Quick Guide
© Lubos Jules Stary,  03/29/2002
CONTENTS
Conventions	3
Recommended Books and Internet Links	3
C program structure	4
Body	4
Function	4
Statement (Command)	4
Block (Compound Statement)	4
PRINTF - Output, SCANF - input	4
PRINTF - Formatting	4
SCANF	5
Escape Sequences	6
Variables	6
Variable Name	6
STATIC Variable	6
Variables Types	7
CONST - Constants	7
Symbolic Constant	8
VOLATILE	8
TYPEDEF	8
Type Conversions	8
Incomplete Types	9
Operators	9
Increment	9
Shorthand Expression	9
Comparison Operators	9
Logical Operators	9
Bitwise Operators	10
Pointer	10
Miscellaneous	10
The Comma "," Operator	10
Order of Precedence	11
Conditionals	11
IF	11
? : Ternary Condition	12
SWITCH	12
Looping	12
FOR	12
WHILE	13
DO-WHILE	13
BREAK	13
CONTINUE	13
GOTO	13
EXIT	14
Arrays	14
Multidimensional Arrays	14
STRING	14
Advanced data types	15
STRUCT	15
Structure Member Access - "." Operator	15
Structure Member Access - "->" Pointer Operator	16
UNION	16
Bit Fields	16
Type-Casting	17
ENUM - Enumerated Types	17
Functions	17
Forward Prototyping (Difference Between DECLARATION and DEFINITION)	18
Parameters and Arguments	18
Return a Pointer	18
VOID Function	19
Array as a Parameter	19
Variable Number of Parameters	19
Pointers	20
Variable - Memory Representation	20
Pointer Manipulation	20
Pointer Arithmetic	21
Pointers and Arrays	21
Array of Pointers	22
Pointers and Structures	22
Linked List	22
Dynamic Memory Allocation	23
Pointer Pitfalls	23
Pointer to Pointer	23
Pointer to Function	24
Complicated Declarations	24
User Input and Output	25
Predefined Streams	25
Keyboard Input	26
Screen Output	26
DISK I/O	26
Filenames	26
FOPEN - Open File	26
File Buffer - FFLUSH	27
File Position Indicator - FSEEK	27
Basic File Functions	27
File - Disk Representation	28
Directory and File Control Routines	29
String Routines	29
Basic String Routines	29
Other String Routines	30
C Function Library	30
Mathematical Functions	30
Time Functions	30
Memory Operations	32
System Controls Routines	32
Preprocessor	32
#DEFINE - Macros and Symbolic Constants	32
#INCLUDE - File	33
Avoiding of Double Including	33
#IF, #ELIF, #ELSE, #ENDIF, #IFDEF, #IFNDEF - Conditional Compilation	33
#UNDEF - Cancel #define	33
Predefined Macros	33
#PRAGMA - Implementation Dependent Directives	34
Advanced Compiler Use	34
Modular Programming	34
Command-Line Arguments	35
C Overview	36
C Statements	36
Advanced Data Types	36

Conventions
Font	Represents
CAPITALS	C language key words.
courier	A program code.
bold	A new term or important thing.

Mark	Represents
NOTE:	Something important but not critically dangerous.
ATTENTION:	Very important, dangerous, can lead to a program crash.
Recommended Books and Internet Links
Peter Aitken, Brad Jones - Sams Teach Yourself C in 21 Days
(Online: www.informit.com/Sams Teach Yourself C in 21 Days)

© 2002, Lubos Jules Stary
C program structure
The comment is closed into symbols /* comment */ ,  and can be placed anywhere.
Body
The body of the main program:
#include <stdio.h>	/* the preprocessor commands - include content of the header file */
	/* types definitions */
	/* functions prototypes - functions types and variables */
int i,j;	/* global variables */
	/* functions */
main()
{	/* begin - Pascal*/
    printf("Hello world \n");	/* function call */
}	/* end - Pascal*/
Function
A function structure:
type function_name (parameters)
{
    local variables;
    C Statements (commands and functions);
}
If the type definition is omitted, the default type is integer. 
Statement (Command)
Every statement ends by the semicolon ";".
Block (Compound Statement)
A sequence of declarations, definitions, and statements enclosed within curly braces "{}" is called a ”block.” (compound statement) 
PRINTF - Output, SCANF - input
PRINTF - Formatting
The output string is closed in "xxx",  variable data have the format character "%":
%[flags] [width] [.precision] [prefix] type

Type	Meaning	
%c	character	
%s	string	
%d	signed integer (decimal)	
%f	double (float) - decimal notation - form "[ – ]dddd.dddd"	
%u	unsigned integer	
%X	unsigned hexadecimal integer - form "ABCD ..."	
%p	pointer to void - form "SSSSOOOO" - segment, offset in uppercase hexa	
%e	double - scientific notation - form "[ – ]d.dddd e [sign]ddd"	
%g	f or e type by decision , e is used if the exponent > 4 or <-4, zeros are truncated, the decimal point appears only when some digits folow it	

Flag	Meaning	Default	
0	zeros adding until the defined width	no prefix zeros	
-	the left align within the defined width	right align	
+	the prefix of the output value with sign +/-	only negative values sign '-'	
' '	(space) positive values will be prefixed with ' '	no space	

Width	Meaning	
1..XXX	minimum printed characters. 
If the number of characters is less, spaces are added.
If the number of characters is greater, all characters are printed (no truncated).	
*	the width specification will be supplied by argument value - variable	

Precision	Type - Meaning	
1..XXX	f - the number of digits after the decimal point. The last digit is rounded.
d - the minimum number of digits. If the number of digits is less, zeros are added to the left
s - the maximum number of characters. If the string is longer, it's TRUNCATED.	
*	the width specification will be supplied by argument value - variable	
Prefixes are only Microsoft specific, not ANSI compatible.

Prefix	Type	Meaning	
l	d,u	long int	
h	d,u	short int	

Output examples: 
char   ch = '@';
char *s = "computer";
int   i = 1234, w=255, width=15;
float f = 12.3456f;

/* example ................................ output */
printf("Integer : |%8d|\n",i);       /* Out :  |    1234| */
printf("Integer : |%-8d|\n",i);      /* Out :  |1234    | */
printf("Hexa    : |%04X|\n",w);      /* Out :  |00FF| */
printf("Float   : |%10.2f|\n",f);    /* Out :  |     12.35| */
printf("String  : |%15s|\n",s);      /* Out :  |       computer| */
/* Speciality */
printf("String  : |%15.3s|\n",s);    /* Out :  |            com| */
printf("Integer : |%15.8d|\n",i);    /* Out :  |       00001234| */
printf("Integer : |%*d|\n",width,i); /* Out :  |           1234| */

SCANF
The input has the same rules, the function is "scanf" and before a variable is the character "&" - this is the address of the variable.
%[width] [prefix] type

Example:
printf("Enter a char and an integer: ");
scanf("%c %i",&ch,&i);

Escape Sequences
Esc seq	Meaning	
\n	new line	
\r	carriage return	
\f	form feed	
\t	tab	
\'	single quotation	
\"	double quotation	
\\	backslash	
\?	question mark	
\xhhh	ASCII char in hexa notation	
\a	Alert = Bell	
Variables
The definition:
var_type var1, var2, varx; 
int i, j, k;
Variables initialisation:
unsigned char ch='A', ch2;
int i=j=3;
Global variables - are defined above main() - are valid in whole program.
Local variables (local scope) - are defined inside a function - are valid only inside the function. A local variable with the same name as a global variable hides the global variable.
Variable Name
Names of variables are case sensitive, 'k' is not equal 'K'. A name can have 247 characters (Microsoft C, ANSI C = 31). 
Allowed characters 'a'..'Z', '0'..'9', '_'. The first char must be a letter 'a'..'Z'.
Style of Variables
This is a classic style:
•	int xpoint; - all small - a variable name.
•	int xshow(); - all small - a function name.
•	#define MAXARRAY 100 - all capital - a constant name.
•	int box_point; - underscore to separate words.
STATIC Variable
Local Variable
A normal local variable inside any function die after end of the function. A static variable persist. At the next function call the static variable has the same value as at leaving. It is only initialised once (at the first call of the function). 
static typename variablename;

static int x;
The static variable is initialized to "0" by default.
Global Variable
If a global variable is defined as static, then it is visible only in its own source file = an internal linkage.
If a global variable is defined as extern (by default - without keyword),  then it is visible in the all program.
Variables Types

Type Name	Bytes	Other Names	Range of Values	
int	*	signed, signed int	System dependent	
unsigned int	*	unsigned	System dependent	
char	1	signed char	-128 to 127	
unsigned char	1	none	0 to 255	
short	2	short int
signed short int	-32,768 to 32,767	
unsigned short	2	unsigned short int	0 to 65,535	
long	4	long int
signed long int	-2,147,483,648 to 2,147,483,647	
unsigned long	4	unsigned long int	0 to 4,294,967,295	
enum	2	none	-32,768 to 32,767	
float	4	none	3.4E +/- 38 (7 digits)	
double	8	none	1.7E +/- 308 (15 digits)	
long double	10	none	1.2E +/- 4932 (19 digits)	
* (pointer)	4	none	seg 0 to 65,535 : offset 0 to 65,535	
Signed and unsigned are modifiers that can be used with any integral type.
The char type is signed by default, but you can specify /J to make it unsigned by default.
The int and unsigned int types have the size of the system word. This is two bytes (the same as the short and the unsigned short) on MS-DOS and 16-bit versions of Windows. However, a portable code should not depend on the size of int.
CONST - Constants
A definition with the const keyword means that this object is not modifiable.
const int maxx=5; /* the program can't modify maxx */

type	Initialization	
char	'A'	
string	"text"	
integer	1234u or U - unsigned
1234l or L - long	
hexadecimal	0x2F	
float	12.34f or F
-25E-4 = -0.0025	
long double	12.34l or L	
array	[2][3]={{1,2,3},{4,5,6}};
[2][10]={"John","Michael"};	
struct	struct guns pistol={"Uzi",30,7};	
float - a floating point constant (e.g. "3.14") has the default type = double. You can retype it with suffixes f / F - float, l / L - long double.
string - a string constant is written to the array plus there is added the terminator '\0'
char textvar[6]="abc";  /* 6 bytes */
char text2[]="a";       /* 2 bytes */
char ch1='a';           /* 1 byte  */
In the memory is:
textvar[10]={'a', 'b', 'c', '\0','\0','\0'}; /* 6 bytes */
Writing of a long string:
unsigned char string[]="abcdefghijklmnoprstuvwxyz123456789*-+<>#@{}&*"
"ABCD";
You don't have to write an array dimension - "[]". If you want to continue writing a long string on the next line, close all substrings to apostrophes " ".
Symbolic Constant
Better using of constants is defining symbolic constants instead of direct using of numbers and chars. The compiler will exchange the text with the defined constant value. #define definition can be anywhere in a program.
#define  MAXARRAY  100    /* ATTENTION! there is no semi-colon ';'*/char store_char[MAXARRAY];
This definition: const short int maxarray=100; occupies 2 bytes in memory, #define occupies nothing.
ATTENTION: #define is valid in whole program despite of defining inside of a function! Therefore the better way is to define a symbolic constant whereby an enumerated type.
An another way for a symbolic constant is to use an enumerated type:
enum{FALSE=0,TRUE=1};
i=TRUE;

enum {MAX1=3,MAX2=2};
int ar[MAX1][MAX2]={{00,01},{10,11},{20,21}};
A constant variable  is not a symbolic constant:
const int MAXX=5;
int ar[MAXX];  /* ILLEGAL! */
VOLATILE
volatile type qualifier means that an external program can change this variable (a multitasking environment) and therefore the code for this variable must be generated regardless of optimization by compiling.
int volatile ivar;
TYPEDEF
Own types definiton:
typedef char mychartype; /* definition */
mychartype nextchar;     /* using */
Type Conversions
•	A character type can be used as an integer and vice versa.
•	If one of operands in an expression is of MASTER type, the other operand (SLAVE) is converted to the proper type. Priority 1 is the highest - it is searched first.

Priority	MASTER type	SLAVE type	SLAVE conversion	
1	long double	any	long double	
2	double	any	double	
3	float	any	float	
4	unsigned long	any integer	unsigned long	
5	long	unsigned int	unsigned long	
6	long	any integer	long	
7	unsigned int	any integer	unsigned int	
8	any integer	any integer	int	
Incomplete Types
An incomplete type can be:
•	A structure type whose members you have not yet specified.
•	An union type whose members you have not yet specified.
•	An array type whose dimension you have not yet specified. 
Array:
unsigned char a[];   /* incomplete type declaration */
unsigned char a[30]; /* complete type declaration - later in the */
                     /* source file */
Operators
Assignment is "=" : i=3; i = 3.
Increment
An increment is "++", a decrement "--". x++ is faster then x=x+1.
Pre-fix: ++x means incrementing is BEFORE using:
k=++x;    is equal   x=x+1; k=x;
Post-fix: x++ means incrementing is AFTER using:
k=x++;    is equal  k=x; x=x+1;
Shorthand Expression
var1 operator = var2  is equal  var1 = var1 operator var2 (faster code).
x+=3;    is equal  x=x+3;
ATTENTION: x*=y+2 means x=x*(y+2) and NOT x=x*y+2 !
Comparison Operators
Operator	Meaning	
==	equal	
!=	not equal	
>	greater than	
<	less than	
>=	gtreater or equal than	
<=	less or equal than	
►	Assignment "=" versus Comparison "=="
ATTENTION: if (a=b) is legal, TRUE if b!=0, FALSE if b==0.
Logical Operators
Operator	Meaning	
&&	AND	
||	OR	
!	NOT	
The value of a logical expression evaluation:
TRUE  != 0
FALSE == 0

Bitwise Operators
Operator	Meaning	
&	Bitwise AND	
|	Bitwise OR	
^	Bitwise XOR	
<<	Left shift	
>>	Right shift	
~	Negation all bits	
Shift:
x=x<<2; /* left shift of bits: 0000 0010, x<<2, 0000 1000 */
The shift left is equivalent to the multiplication by 2, the shift right is equal to the division by 2 - but much faster.
One's complement:
x=~x; /* 0000 0010, ~x, 1111 1101 */
Pointer
Operator	Meaning	
&	Address of object - &x	
*	Pointer to object - *x	
Example:
unsigned char byte1;
unsigned char *pbyte1=&byte1; /* pointer pbyte1 points on */
                              /* memory address of variable byte1 */
Miscellaneous
Operator	Meaning	
(type)	Type cast	x=(int)y;	
sizeof	Size of object 	x=sizeof(y);	
%	Modulus - rest after integer dividing.	x=10%3; /* x==1 */	
.	Structure (record) member	rec.mem	
->	Pointer to structure member	
,	Sequential evaluation	
The Comma "," Operator
The comma "," operator of a sequential evaluation - allows grouping many statements where one is expected. Expressions are evaluated from left to right. The result of this sequention is the type and the value from the last expression - right.
for (i=0,j=0,k=0;i<8;++i);
void fun1(int x1,int x2);  /* declaration */
fun1((--j,k+3),m);         /* calling - x1=k+3 */

Order of Precedence
Symbol	Type of Operation	Annotations	
()   []   –>   .	Expression	->  pointer to structure member	
!   ~   ++   ––
sizeof   (type)
&   *   +   –	Unary	!   NOT (logical)
~   negation all bits (bitwise)
(type)   type cast
&   address of an object
*   pointer	
*   /   %	Multiplicative	%   modulus - rest after integer dividing	
+   –	Additive		
<<   >>	Bitwise shift		
<   >   <=   >=	Relational		
==   !=	Equality	!=  not equal	
&	Bitwise-AND		
^	Bitwise-exclusive-OR		
|	Bitwise-OR		
&&	Logical-AND		
||	Logical-OR		
? :	Conditional-expression		
=    *=   /=    %=
+=   –=   <<=   >>=
&=   ^=   |=	Simple and compound assignment
(right to left associativity)	x+=3;    is equal  x=x+3;	
,	Sequential evaluation		
The short table with the precedence of symbols used by declarations:
Priority	Symbol	Note	
1	()	left to right associativity	
2	[]	left to right associativity	
3	*	right to left associativity	
The short table with the precedence of symbols used by arithmetic operations:
Priority	Symbol	
1	++  --	
2	*   /    %	
3	+   -	
The short table with the precedence of symbols used by relational operations:
Priority	Symbol	
1	<   >   <=   >=	
2	==  !=	
3	&&	
4	||	
Conditionals
IF
if (expression)
	statement1;
else
	statement2;
if expression>0 (TRUE) then do statement1 else do statement2.
ATTENTION: The C compiler doesn't have control for a bad expression definition - "=" instead of "=="!
if (a=b) is legal, TRUE if b!=0, FALSE if b==0.
? : Ternary Condition
More effective code.
expression1 ? expression2 : expression3
It means: 
if expression1 then expression2 else expression3
For example to assign the maximum of a and b to z: 
z = (a>b) ? a: b;
what is the same as: 
if (a>b)
    z=a;
else
    z=b;
SWITCH
switch (expression) 
{
    case const1: statement1; break;
    ...
    case constx: statementx; break;
    default:     statement;  break;
}
If you don't put the break there, the next case will get evaluated.
We can also have a NULL statement case constx:
switch (letter)
{
    case '+':
    case '-':
    case '=': ++numberofsignes; break;
    default: ++numberofchars; break;
}
If letter == '+' or '-' or '=' then ++numberofsignes.The expression is evaluated, and if it matches any of the case values, execution jumps to that line. 
Looping
FOR
for (init_expression;cond_expression;loop_expression)
    statement;
init_expression = initialisation - evaluated only once before the first iteration.
cond_expression = terminate test - evaluated BEFORE an every iteration - TRUE != 0.
loop_expression = modifier - evaluated AFTER an every iteration.
Loop execution:
1.	init_expression - initialisation.
2.	cond_expression - evaluation
cond_expression==0 - end of the loop, jump to the next statement under the loop
cond_expression!=0 - execute statement, go to step 3
3.	statement - evaluation.
4.	loop_expression - evaluation (increment), go to step 2.

for (x=1; x<=8; ++x)
{
    printf("x=%d \n",x);
}
/* after the end of the last loop is x=9 */
Every expression can consist of multiple expressions separated by ",".
for (x=300, y=7; x; x/=10) ...
This loop will continue until x becomes 0.
There can be no expression, no expression is evaluated as == "1". Omitted cond_expression == TRUE and termination of this loop is possible only by statements BREAK, RETURN and GOTO.
for (; ; ;) ...
Never-ending loop.
BREAK terminates the loop without evaluation loop_expression.
CONTINUE causes a jump to the start and evaluation loop_expression.
WHILE
while (expression)
    statement;
If the expression is initially false, the body of the while statement is never executed.

x=3;
while (x>0)
{
    printf("x=%d\n",x);
    --x;
}
The expression can be any expression, not only a condition. If the expression == 0, it is the end of loop:
while (--x)...
DO-WHILE
do
    statement;
while (expression);
The body of the loop is always executed at least once.

x=3;
do
{
    printf("x=%d\n",x);
    --x;
}
while (x>0);
BREAK
The exit from loop - the jump out of the loop, under the end of the loop block.
CONTINUE
The jump to the start of loop - evaluation loop_expression.
GOTO
The jump to the label.
goto stop;
stop: ...
EXIT
Terminating a program. You must include header file stdlib.h.
exit();   /* normal exit */
exit(0);  /* normal exit */
exit(3);  /* Error code */
Arrays
Declaration:
int listofnumbers[50]; /* idexes [0] .. [49]*/
BEWARE: The index starts at 0 value!
ATTENTION: The C compiler doesn't have control for a bad array index - neither by compiling, nor by running!
The access to the elements:
thirdnumber=listofnumbers[2];
listofnumbers[5]=100;
Multidimensional Arrays

enum {ROWS=3,COLS=3};
int multi[ROWS][COLS] = { {00,01,02}, {10,11,12}, {20,21,22} }; /* INIT */
Logical representation:
      ┌────┬────┬────┐
row 2 │ 20 │ 21 │ 22 │
      ├────┼────┼────┤
row 1 │ 10 │ 11 │ 12 │
      ├────┼────┼────┤
row 0 │ 00 │ 01 │ 02 │
      └────┴────┴────┘
column   0    1    2
Memory representation:
        │<─  row 0   ─>│<─  row 1   ─>│<─  row 2   ─>│
        ┌────┬────┬────┬────┬────┬────┬────┬────┬────┐
        │ 00 │ 01 │ 02 │ 10 │ 11 │ 12 │ 20 │ 21 │ 22 │
        └────┴────┴────┴────┴────┴────┴────┴────┴────┘
offset     0    1    2    3    4    5    6    7    8
STRING
The string in C is an array of chars.
char name[50];
C doesn't have facility for direct handling with strings:
name="John";  /* Illegal operation!*/
name=name+"Fitzgerald"; /* Illegal operation!*/
You have to use special string handling functions.
strcpy(name,"John");  /* correct */
strcat(name,"Fitzgerald"); /* correct */
In order to use variable length strings the '\0' character is used as END string indicator.
The string initialization:
unsigned char sa[5]="abc";
/* memory content: unsigned char sa[5]={'a','b','c','\0','\0'} */
/* rest of string is filled by '\0' characters */

unsigned char sa[]="abc";
/* the memory content: unsigned char sa[4]={'a','b','c','\0'} */
/* the compiler creates the proper size of array (string) */
ATTENTION: When you copy to the string variable a longer string as its string dimension, you will damage a part of memory behind the string! No control from C compiler!
unsigned char sa[]="abc"; /* reserved memory space = 4 bytes */
strcpy(sa,"abcdefgh");    /* you overwrite 9 bytes of memory  */
                          /* unpredictable results of program */
NOTE: Therefore use strncpy function instead of strcpy!
strcpy(dest,source); // when source is longer the it damage memory
strncpy(dest,source,sizeof(dest)-1); // protection against overwriting
Advanced data types
STRUCT
This is similar to the record in Pascal (the database record).
struct type_name	/* this type_name is valid only with keyword struct */
{
    type variable_name1;
    type variable_name2;
} structure_variable;
Or:
struct type_name structure_variable;
Example:
struct guns    /* type definition */
{
    char name[50];
    int magazinesize;
    float calibre;
};

struct guns pistol;   /* variable definition */
type_name and structure_variables are optional. You can write also:
struct
{
    ...
} johns;  /* direct definition of variable */
typedef can also be used with structures - this is more logical:
typedef struct
{
    ...        /* type definition */
} bigguns;     /* this type_name is valid all alone */

bigguns pistol;   /* variable definition */
Initialization:
struct guns pistol={"Uzi",30,7};
Structure Member Access - "." Operator
An access to a member (or field) of a structure is through "." operator:
pistol.magazinesize=100;
It is also possible to use arrays of structures:
bigguns shotgun[10];
Access:
shotgun[1].calibre=38;
Structure Member Access - "->" Pointer Operator
The pointer to the member:
bigguns *pgun;

(*pgun).calibre=3.8;
pgun->calibre=3.8;
UNION
The union is a structure (record) with a variable length and a variable content. The C compiler allocates  memory for the biggest member.
union type_name
{
    type variable_name1;
    type variable_name2;
} union_variable;
NOTE: All members started from the same address in memory.
typedef union
{
    int maxpassengers;
    float maxpayload;
} typeload;

typedef struct
{
   unsigned char planetype;
   typeload planeload;
}typeplane;
typeplane myplane;
Access:
myplane.planeload.maxpassengers=120;
Usual usage of an union is as a variable end of a struct (record).
Bit Fields
Bit fields allow to operate over couple of bits in a machine word.
struct 
{
    unsigned short      icon : 8; /* 8 bits field */
    unsigned short     color : 4;
    unsigned short underline : 1;
    unsigned short     blink : 1;
} screen;
Access:
screen.icon=0xFE;
Restrictions:
•	The bit field must be a member of a structure or an union.
•	Type of the variable must be an integer.
Bit fields are always converted to an integer type.

Type-Casting
Type-casting is is forcing one variable of one type to be an another type.
The cast operator is "()".
(forcedtype)variable;
Example:
int integernumber=10;
float floatnumber;

floatnumber=(float)integernumber;   /* floatnumber=10.0 */
ENUM - Enumerated Types
The enumerated type contain a list of constants that can be addressed by an integer value.
enum type_name{ name1, name2=init_val } enum_variable;
The first enumerated constant name has index value 0. You can overwrite the value of any enumerated name, the next value will be the previous value + 1.
typedef enum
{
   saturday,                 /* saturday = 0 by default */   sunday = 0,               /* sunday = 0 overwritten value */   monday,                   /* monday = 1 (sunday + 1)*/   tuesday,                  /* tuesday = 2 */   wednesday,                   thursday,   friday} Days;         /* Declare enum type Days */  
Days today;      /* Variable today has type Days */
today=2;   /* Many possible assignments */ 
i=tuesday;
today=wednesday;
Functions
Definition:
returntype fn_name(parameterdef1, parameterdef2,...)
{
    localvariables;
    functioncode;
    return(return_value);
}
The return statement can be in the function body more then once - typicaly in conditional statements. The return statement will finish the function.
Example:
float findaverage(float a, float b)
{
    float average;

    average=(a+b)/2;
    return(average);  /* return result */
}
Calling:
res=findaverage(a,b);
fn_name();  is the function calling.
fn_name;    is the address of the function = the address of the function entry point.
Recursion - it's possible to call the function from inside of the same function.
Nesting - a definition of a subfunction inside of a mother function is forbidden.
Forward Prototyping (Difference Between DECLARATION and DEFINITION)
Declaration - you can declare the prototype of the function before the basic definition - for example because of cross calling. It's simply to say, header of function:
float findaverage(float a, float b); /* DECLARATION = forward prototyping*/

float findaverage(float a, float b)  /* DEFINITION */
{
	...
}
Definition - full definition of the function with the body.
Parameters and Arguments
Parameter - a name in the function definition (the parameter is the local variable).
Argument - a value in the function calling.
The group definition of parameters is forbidden:
void funx(int i,k);      /* compiler error */
void funx(int i,int k);  /* O.K. */
The variable number of arguments - the parameter list can be terminated by the ellipsis notation, the comma followed by three periods (, ...).
It exists 2 types of parameters:
Passed by value - the value in the argument is copied to the internal variable (located in the stack). Changing of the parameter inside of the function, doesn't have effect on the argument variable.
void funx(int i)	/* definition */
{
    ++i;
}

j=5;
funx(j);	/* calling - variable "j" doesn't change */
	/* j=5 */
Passed by address - the memory address of the argument is copied to the internal variable = pointer. Changing of the parameter change directly the argument variable.
void funx(int *i)	/* definition - pointer to integer*/
{
    ++*i;
}

j=5;
funx(&j);	/* calling - variable "j" will change */
	/* j=6 */
ATTENTION: The order of arguments evaluation is WITHOUT GUARANTEE!.
add( i + 1, i = j + 2 ); /* unknown order - unpredictable results*/
Return a Pointer

int *funp(int *inp)  /* function returns pointer to int */
{
    return(inp);     /* return address stored in variable inp */
}

y=*funp(&x1);  /* parameter inp=&x1, return variable inp==&x1 */
               /* *funp()==*inp==x1, therefore y==x1 */
ATTENTION: You can not return the address of a local variable defined inside the function - the stack content is without guarantee after the function return!
int *funp(int *inp)  /* function returns pointer to int */
{
    int locx;         /* stack memory */

    locx=*inp;
    return(&locx);   /* NOT PREDICTABLE RESULT */
}
VOID Function
The void function provides a way of emulating PASCAL type procedures.
If you do not want to return a value, you must use the return type void and omit the return statement.
Declaration:
void squares();
Calling:
squares();
You must have parenthesis "()" even for no parameters function.
Array as a Parameter
Single dimensional arrays can be passed to functions as a parameter as follows:
By the declaration:
int strlen(char str[]);  /* char str[]==char *str */
int strlen(char *str);
char str[] - this is pointer to first member of array. You can use also str[x] but it's useless.
int length;
#define MAXSTR 10
unsigned char str[MAXSTR]="Hallo";

length=strlen(str);      /* str==&str[0] */
length=strlen(&str[0]); 
ATTENTION: An array parameter is in fact a pointer, therefore when you change an array element inside of function, it changes also an original array (parameter)!
Multidimensional Arrays
void printtable(int xsize, int ysize, float table[][5])
... float table[][]) /* not allowed */
C compiler needs to know data size between two jumps of the first index.
float table[][5] means - jump from table[0][0] to table[1][0] is 5 x sizeof(float).
Variable Number of Parameters
A function calling is controlled by macros from STDARG.H. One declared parameter is an obligation.
#include <stdarg.h>
void funx(int max,...)
{
	va_list arglist; /* array of arguments + index (pointer) */
	int xarg,val;

	va_start(arglist,max); /* obtains last declared argument = max, */
                          /* end set first argument from variable set */
	for (xarg=1;xarg<=max;++xarg)
	{
		val=va_arg(arglist,int); /* obtain argument of type int, */
                                  /* move pointer to next argument */
		printf("Parameter n. %d,   value = %d\n",xarg,val);
	}

	va_end(arglist); /* stack tiding, correct return */
}
Pointers
Variable - Memory Representation
A variable storing in the memory:
example : unsigned long i=257;

Memory   : Higher address                                Lower address
bits     : 31  ..  16 ┌15┬14┬13┬12╥11┬10┬09┬08┐ ┌07┬06┬05┬04╥03┬02┬01┬00┐
 content :  0  ..   0 │ 0│ 0│ 0│ 0║ 0│ 0│ 0│ 1│ │ 0│ 0│ 0│ 0║ 0│ 0│ 0│ 1│
                      └──┴──┴──┴──╨──┴──┴──┴──┘ └──┴──┴──┴──╨──┴──┴──┴──┘
bytes    : 3 - 2 byte           1 byte                    0 byte (lowest)
 content : 0x00 0x00            0x01                      0x01
address  : 0040:0023 0040:0022  0040:0021              0040:0020
Memory address structure:
          SEGMENT : OFFSET
address :   00 40 : 00 20
            Hi Lo : Hi Lo byte
Pointer Manipulation
A pointer is a variable which contains the memory address of an another variable.
Indirection - means accessing the value at the address held by a pointer. The pointer provides an indirect way to get the value held at that address.
The indirection operator (*) -- called also the dereference operator -- in front of the variable pointx means "the value stored at the address in pointx".
int x=1,y=8; /* x, y == variables - containes data */
int *pointx=&x; /* int * = pointer to int */
                /* &x    = address of the variable x */ 
                /* variable pointx contains address of variable x */
void *point; /* VOID == universal generic pointer */
The indirection operator (*) is also called the dereference operator. When a pointer is dereferenced, the value at the address stored by the pointer is retrieved.
y=*pointx; /* access to the x variable, pointx==&x, *pointx==x */
We store the address of the variable x (seg:ofs) to the variable pointx (to its memory location==address).
pointx=&x;
                     ┌─────────┐     ┌─────────┐          ┌─────────┐
variable content : x │        1│   y │        8│   pointx │0040 0010│
                     └─────────┘     └─────────┘          └─────────┘
  memory address :    0040:0010       0040:0020            0040:0500
We move data from the memory address where points the variable pointx (the address of the variable x) to the variable y. After that x==y.
y=*pointx;
                     ┌─────────┐     ┌─────────┐          ┌─────────┐
                   x │        1│   y │        1│   pointx │0040 0010│
                     └─────────┘     └─────────┘          └─────────┘
                      0040:0010       0040:0020            0040:0500
We store a constant data to the address where points the variable pointx (the address of the variable x). The variable x will change.

*pointx=666;
                     ┌─────────┐     ┌─────────┐          ┌─────────┐
                   x │      666│   y │        1│   pointx │0040 0010│
                     └─────────┘     └─────────┘          └─────────┘
                      0040:0010       0040:0020            0040:0500
We move data from the variable pointx (the address of the variable x) to the variable y.
y=pointx;
                     ┌─────────┐     ┌─────────┐          ┌─────────┐
                   x │      666│   y │0040 0010│   pointx │0040 0010│
                     └─────────┘     └─────────┘          └─────────┘
                      0040:0010       0040:0020            0040:0500
Pointer Arithmetic
Examples:
int x=1;
int *pointx=&x,*pointy; /* for example &x==0040:0010 */

pointy=pointx;       /* assignment pointer to pointer */
Increment (++) add to memory address, stored in pointer variable, number equal to size of type of pointer. sizeof(int)==4 therefore addition is + 4.
++pointx;            /* + 4 bytes, address=0040:0014 */
pointx=pointx+1;     /* the same result */
pointx=pointx+2;     /* + 2 x 4 bytes, address=0040:0018 */
ATTENTION!:
*pointx++;           /* increments address NOT value - address=0040:0014 */
(*pointx)++;         /* increments value - x = 2 */
Pointers and Arrays
Principles of arrays and pointers are very close. An array name is a constant pointer to the first element of the array.
enum {MAXA=10};
unsigned char ar[MAXA]={10,11,12,13,14,15,16,17,18,19};
unsigned char *par
unsigned char ca,cp;

par=ar;      
par=&ar[0];  /* ar==&ar[0] */
/* array arithmetic ==   pointer aritmetic */
ar[0]=0;	*par=0;
ar[1]=1;	*(par+1)=1; /* ar[1]==*(par+1) */
ar[2]=ar[1]*3;	*(par+2)=*(par+1)*3;
ca=ar[2];	par=ar+2;  cp=*par;
ca=ar[2];	par=&ar[2]; cp=*par;
NOTE: It's possible to exchange references of arrays and pointers: 
ca=*(ar+2);
par=ar;
cp=par[2];  /* ar[2]==*(ar+2)==par[2] */
++par;      /* now *par==ar[1] */

      ar[0]    ar[1]    ar[2]              ar[7]
   ┌────────┬────────┬────────┬─────────┬────────┐
ar │       0│       2│       4│    ...  │      64│
   └────────┴────────┴────────┴─────────┴────────┘
       *par   ++*par  *(par+2)           *(par+7)
Differencies between a pointer and an array:
•	A pointer is a variable. We can do par=ar and par++. 
•	An array is not a variable. ar=par and ar++ ARE ILLEGAL.
Array of Pointers
Differencies between declarations:
int (*a)[35]; /* declares a pointer to an array of 35 ints */
   /* we need parenthesis (*a) since [] have a higher precedence than * */
int *a[35]; /* declares an array of 35 pointers to ints */
Memory saving by using of array of pointers:
/*array of strings*/
unsigned char arnames[][20]={"first","secondary","third"};
/* array of pointers to strings */
unsigned char *pnames[]={"first","secondary","third"};
Memory representation:
arnames (size = 60 bytes)
	20 bytes	
0	first\0	
1	secondary\0	
2	third\0	
pnames (size = 12 bytes, strings = 22 bytes, total = 34 bytes)
	4 bytes	

6 bytes

first\0

0		

10 bytes

secondary\0

1		
2		

6 bytes

third\0

Pointers and Structures
Definition:
struct TCOORD {float x,y,z;} coord;
struct TCOORD *pcoord;
pcoord=&coord;
The different way of a definition:
typedef struct {float x,y,z;} TCOORD;
TCOORD coord;
TCOORD *pcoord;
The access to a member:
(*pcoord).x=1.23f;
pcoord->x=1.23f;     /* '->' pointer to member */
Linked List
The linked list is a sequence of structures (records) in the memory, where each record contain a pointer to the next record.
struct TELEMENT 
{
    int value;
    struct TELEMENT *pnext;
};
struct TELEMENT e1,e2;

e1.pnext=&e2;

value	pnext		value	pnext	
e1		e2	
Dynamic Memory Allocation
MALLOC
malloc function returns void pointer to the reserved memory space (first byte) or NULL pointer if there is no memory.
void *malloc( size_t size ); /* Declaration, size=bytes */

pval=(int *)malloc(100*sizeof(int));/* Using, type casting is good habit */
if (pval==NULL)
{
    printf("Out of memory\n");
    exit(1);
}
It's not necessary to use type casting  malloc function, void type is compatible with every type.
FREE
void free( void *memblock );

free(pval);  /* release memory block */
Pointer Pitfalls
►	Using not initialized pointer
int val,*pval;

*pval=5;        /* writes data to random part of memory */
ATTENTION: Writing data to the not initialized pointer destroy a part of memory and your program or whole system will crash! C compiler has control for this instance.
Correct is:
pval=&val;   /* init pointer */
►	Bad memory allocation
int *pval;
*pval=(int *)malloc(100);
*pval=5;
malloc returns a memory address that is necessary to write to pval not to *pval. 
Correct is:
pval=(int *)malloc(100);
*pval=5;
Pointer to Pointer
Example:
int val=5;
int *pval=&val;
int **ppval=&pval;

    val==5                /* stored value */
   &val==0040:0030        /* address of variable val */
  *pval==5                /* point to value */
   pval==0040:0030==&val  /* stored address of variable val */
  &pval==0040:0020        /* address of variable pval */
**ppval==5                /* point to point to value */
 *ppval==0040:0030==&val  /* point to variable pval with */
                          /* stored address of variable val */
  ppval==0040:0020==&pval /* stored address of variable pval */
 &ppval==0040:0010        /* address of variable ppval */
Pointer to Function
NOTE: Function name is a constant pointer to the function.
A pointer to a function must point to a function of the appropriate return type and signature.
long * Function (int);  // function with integer parameter, returning long
long (* pFunc) (int);   // pointer to function with integer parameter,
                        // returning long

Example:
void fun2(){ ... } /*  CALLED fun */

void (*pfun)(); /* pointer to function without arguments and */
                /* without returning value */
pfun=fun2;      /* initialization */
pfun();         /* call pfun==address fun2 */
Complicated Declarations
Priority	Symbol	
1	()	
2	[]	
3	*	
A simple way to interpret complex declarators is to read them ”from the inside out,” using the following four steps: 
1.	Start with the identifier and look directly to the right for brackets "[]" or parentheses "()" (if any).
2.	Interpret these brackets or parentheses, then look to the left for asterisks.
3.	If you encounter a right parenthesis at any stage, go back and apply rules 1 and 2 to everything within the parentheses.
4.	Apply the type specifier. 
Examples:
char *( *(*var)() )[10];
 ^   ^  ^ ^ ^   ^    ^
 7   6  4 2 1   3    5
In this example, the steps are numbered in order and can be interpreted as follows: 
1.	The identifier var is declared as
2.	a pointer to
3.	a function returning
4.	a pointer to
5.	an array of 10 elements, which are
6.	pointers to
7.	char values.
Next examples:
int *var[5]; /* (1) var name is (2) an array (3) of pointers */
 ^  ^ ^ ^    /* (4) to int values */
 4  3 1 2
The array brackets "[]" have higher priority than the pointer asterisk "*".
int (*var)[5]; /* Pointer to array of int values */
The parentheses "()" have higher priority than the brackets "[]".
long *var( long, long ); /* Function returning pointer to long */
The function modifiers "()" also have higher priority than the pointer asterisk "*".
long (*var)( long, long ); /* Pointer to function returning long */
The parentheses "()" give the pointer modifier higher priority than the function modifier "()".
struct both       /* Array of pointers to functions */
{                 /*   returning structures         */
    int a;
    char b;
} ( *var[5] )( struct both, struct both );
var is an array of five pointers to function that returns the structure and has 2 arguments structure type.
union sign         /* Array of arrays of pointers */
{                  /* to pointers to unions       */
     int x;
     unsigned y;
} **var[5][5];
User Input and Output
Stream - is a sequence of bytes. 
Text stream - characters organized to lines, which can be up to 255 characters long and are terminated by an end-of-line, or newline, character. Text stream devices - screen, keyboard, printer.
Binary stream - not organized bytes without limits. Binary stream devices - disk files.
Predefined Streams
These streams are automatically opened when a C program starts executing and are closed when the program terminates. There is not necessary to take any special action, streams are always available.

Name	Stream	Device	
stdin	Standard input	Keyboard	
stdout	Standrad output	Screen	
stderr	Standard error	Screen	
stdprn	Standard printer	Printer - LPT1:	
stdaux	Standard auxiliary	Serial port - COM1:	
For example:
printf("Hallo world!"); /* uses stdout stream */
scanf("%d",&x);         /* uses stdin stream */
Display error message
fprintf(stderr,"An error has occurred.");
Print message
fprintf(stdprn,"\nThis message is printed.\r\n");

Function	Description	
standard stream	file stream		
printf()	fprintf()	formatted output	
puts()	fputs()	string output	
putchar()	fputc()	character output	
scanf()	fscanf()	formatted input	
gets()	fgets()	string input	
getchar()	fgetc()	character input	
All this functions are in stdlib.h.
EOF - End of file - character is returned when the end of file has been reached or an error has occured.
#define EOF -1  /* in stdio.h */
Keyboard Input
Buffered input - the operating system holds all characters in a temporary storage space until you press Enter, and then the system sends the characters to the stdin stream.
Unbuffered input - the function returns the pressed character immediately.
Echo - each character is displayed on the screen.

Function	Description	
getchar()	Reads a character from the keyboard. Buffer + echo.	
getch()	Reads a character from the keyboard. Unbuffered, no echo. (No ANSI standard)	
getche()	Reads a character from the keyboard. Unbuffered, + echo. (No ANSI standard)	
gets()	Reads a string from the keyboard. Buffer + echo. '\n' changes to '\0'	
scanf()	Reads a string from the keyboard. Buffer + echo. Formatted input	
kbhit()	Check the keyboard for key pressing. Return: not 0 == key pressed.
int _kbhit( void );	
Screen Output

Function	Description	
putchar()	Writes a character to the screen.	
puts()	Writes a string to the screen. Adds a new line character.	
printf()	Writes a string to the screen. Formatted output.	
DISK I/O
Text file - the line length is 0..255 characters, by writing is the newline character '\n' translated to a CR‑LF (carriage return, linefeed) characters, by reading are CR-LF characters translated to '\n'.
Binary file - all data is written and read unchanged.
Filenames
Depends on an operating system. 
Windows 9x/NT:
•	up to 256 characters
•	forbidden characters: / \ : * ? " < > |
•	acceptable characters: - _ # $ ~ & @ + =
•	system path name: c:\data\list.txt
•	C language path name definition: char *filename = "c:\\data\\list.txt";
UNIX uses forward slash '/'.
FOPEN - Open File
Prototype (stdio.h):
FILE *fopen(const char *filename, const char *mode);
•	FILE - it's structure (record), where are written an internal data of the operating system.
If *FILE==NULL, means error by opening.
•	filename - pathname+filename
•	mode - mode of file opening

mode	description	
r	Opens the file for reading. If the file doesn't exist, fopen() returns NULL.	
w	Opens the empty file for writing. If the file doesn't exist, it's created. If the file exists, it's destroyed.	
a	Opens the file for appending. If the file doesn't exist, it's created. If the file exists, new data is appended to the end of file.	
r+	Opens the file for reading and writing. If the file doesn't exist, it's created. If the file exists, new data is written to the beginning of the file, overwriting existing data.	
w+	Opens the file for reading and writing. If the file doesn't exist, it's created. If the file exists, it's destroyed.	
a+	Opens the file for reading and appending. If the file exists, new data is appended to the end of file.	
Second character:
mode	description	
t	Open in text mode - default.	
b	Open in binary mode.	
File Buffer - FFLUSH
The file buffer is a temporary memory block, created by operating system for read/write operations. When your program writes a data to the stream, the data is saved in the buffer until the buffer is full, and then the entire content of the buffer is written, as a block, to the disk. 
When you close a file, the files data buffer is flushed - written to the file, only in this moment you can be sure that your data is written to the disk! When a program terminates, all streams are automatically flushed and closed.
When you want to be sure that your data is written to the disk and you don't wont to close the file you have to use function fflush().
File Position Indicator - FSEEK
The position indicator is a pointer in the file, it points to starting position for read/write operations. Position is number of bytes from the beginning and beginning position is 0.
long ftell(FILE *stream); /* read position indicator */

int fseek(FILE *stream, long offset, int origin); /* move position ind. */
							/* see file functions table */
Basic File Functions
Function	Description	
fopen()	The file open. Return: NULL == error
FILE *fopen(char *filename, char *mode);	
fclose()	The file close. Return: EOF == error, 0 == O.K.
int fclose(FILE *stream);	
fprintf()	Write a formatted string to the file. Return: -1 == error, X == written bytes
int fprintf(FILE *stream, char *format [, argument ]...);	
fscanf()	Read a formatted string from the file. Return: EOF == error, X == read bytes
int fscanf(FILE *stream, char *format [, argument ]...);	
fputs()	Write a string to the file. Return: EOF == error
int fputs(char *string, FILE *stream);	
fgets()	Read a string from the file. n == max. read bytes, read until newline or n-1 charcters. Return:  NULL == error
char *fgets(char *string, int n, FILE *stream);	
fwrite()	Write a binary data to the file. Write the buffer, size == size of 1 item, count == number of items. Return: X == number of written items
int fwrite(void *buffer, int size, int count, FILE *stream );	
fread()	Read a binary data from the file. Read to the buffer, size == size of 1 item, count == number of items. Return: X == number of read items
int fread(void *buffer, int size, int count, FILE *stream );	
fflush()	Writes the disk buffer to the disk. Return: EOF == error
int fflush(FILE *stream);	
ftell()	Read file position indicator. Return: -1 == error, X == position
long ftell(FILE *stream)	
fseek()	Move the file position indicator. offset == distance of moving, origin == relative starting point (SEEK_SET == from the beginning, SEEK_CUR == from the current position). Return: 0 == O.K.
int fseek(FILE *stream, long offset, int origin);	
remove()	Delete file. Return: 0 == O.K.
int remove(char *path);	
feof()	Detecting End of file. Return: 0 == O.K., nonzero == end of file
int feof(FILE *stream);	
errno	Variable with stored error code from last operation.	
strerror()	Get a system error message.
char *strerror(int errno);	
clearerr()	Resets an error indicator for a stream.
void clearerr( FILE *stream );	
Important constants (values for Windows 32 bit):
_MAX_PATH=260; /* Maximum length of full path name */
_MAX_FNAME=256; /* Maximum length of filename */
_MAX_EXT=256; /* Maximum length of extension name */
_MAX_DIR=256; /* Maximum length of directory name */
Example:
FILE *xfile;
unsigned char filename[_MAX_PATH]="..\\test.bin";/*one directory level up*/
enum {AMAX=256};
unsigned char warray[AMAX];
int x,nitems;

xfile=fopen(filename,"wb");
if (xfile==NULL)               /* error check */
{
    printf("Error opening file : %s\n",strerror(errno));
    return(-1);
}

nitems=fwrite(warray,sizeof(unsigned char),AMAX,xfile);
if (nitems!=AMAX)          /* error check */
{
    printf("Error opening file : %s\n",strerror(errno));
    return(-1);
}
fclose(xfile);
File - Disk Representation
A variable storing on the disk:
struct rec
{
    int x;
    int y;
} rec1;

rec1.x=15;  /*  15==0x0F */
rec1.y=255; /* 255==0xFF */
/* written to the binary file */

File position: ┌00┬01┬02┬03╥04┬05┬06┬07┐
content:       │0F│00│00│00║FF│00│00│00│
               └──┴──┴──┴──╨──┴──┴──┴──┘
variable:      └     x    ┘ └    y     ┘
byte:           Lo       Hi
Directory and File Control Routines
direct.h, io.h
Function	Description	
chdir()	Change the current working directory.	
chdrive()	Change the current drive.	
mkdir()	Make the new directory.	
rmdir()	Remove the directory.	
findfirst()	Find the file with specified attributes.	
findnext()	Find the next file with specified attributes.	
String Routines
Routines are defined in string.h.
Basic String Routines
Function	Description	
strlen()	Get the length of  a string == number of chars without null character.. size_t == unsigned int.
size_t strlen(char *string);	
strcpy()	Copy a string from strSource to strDest including null character. Return: strDest.
char *strcpy(char *strDest, char *strSource);	
strncpy()	Copy count characters from strSource to strDest. Don't includes automatically null character. Return: strDest.
char *strcpy(char *strDest, char *strSource, int count);	
strcat()	Append a string (concatenation). Append strSource onto the end of strDest. Return: strDest.
char *strcat(char *strDest, char *strSource);	
strcmp()	Compare strings. Comparing process ends by the first different chars, and compare ASCII value of these chars. Return: 0 == identical strings, <0 == string1 < string2, >0 == string1 > string2.
int strcmp(char *string1, char *string2);	
strstr()	Find a first occurence of str2 in str1. Return: pointer to first char of substring, NULL == not found.
char *strstr(char *str1, char *str2);	
strlwr()	Converts all the letter characters in str from uppercase to lowercase. It changes str! Return: pointer to str.
char *strlwr(char *str);	
strupr()	Converts all the letter characters in str from lowercase to uppercase . It changes str! Return: pointer to str.
char *strupr(char *str);	
atoi()	Conversion - ASCII to integer. Spaces are ignored, conversion stops by unconvertible character encountering. Return: X == converted value, 0 == error.
int atoi(char *string);	
itoa()	Conversion - integer to ASCII. radix == base of value (10,16,2). Return: pointer to str.
char *itoa(int value, char *str, int radix);	
isalpha()	Returns TRUE if ch is a letter. int isalpha(int ch);	
isdigit()	Returns TRUE if ch is a digit. int isdigit(int ch);	
isspace()	Returns TRUE if ch is a white space character - space, tab, vertical tab, line feed, form feed, or carriage return. int isspace(int ch);	
sprintf()	Write formatted data to the string. Return: X == written characters
int sprintf(char *buffer, char *format [, argument] ... );	
sscanf()	Read formatted data from the string. Return: EOF == error, X == read and converted fields
int sscanf(char *buffer, char *format [, argument ] ... );	
ATTENTION: When you copy to the string variable longer string how is the string dimension, you will damage a part of memory behind the string! No control from C compiler!
Other String Routines
Function	Description	
strncpy()	Copy N characters from Source to Dest.	
strncat()	Append a N characters from strSource.	
strchr()	Find a first occurence of the character in a string. Return: pointer to char.	
strrchr()	Find a last occurence of the character in a string. Return: pointer to char.	
strcspn()	Find a first occurence of any character from string2 into string1.	
strspn()	Find a first character that doesn't match a character in string2.	
C Function Library
Mathematical Functions
math.h
Function	Description	
abs()	Returns absolute value	
modf()	Splits x into integral and fractional parts. double modf(double x, double *i)	
fmod()	Returns the floating-point remainder of x/y.	
srand()	Sets a random starting point.	
rand()	Generates a pseudorandom number.	
Time Functions
time.h
Variables:
/* MS-DOS time = number of seconds since 01.01.1970 00:00:00 */
typedef long time_t, clock_t; 
/* Formatted time */
struct tm {
    int tm_sec;     /* seconds after the minute - [0,59]  */
    int tm_min;     /* minutes after the hour - [0,59]    */
    int tm_hour;    /* hours since midnight - [0,23]  */
    int tm_mday;    /* day of the month - [1,31]      */
    int tm_mon;     /* months since January - [0,11]      */
    int tm_year;    /* years since 1900               */
    int tm_wday;    /* days since Sunday - [0,6]      */
    int tm_yday;    /* days since January 1 - [0,365] */
    int tm_isdst;   /* daylight savings time flag     */
};

Function	Description	
time()	Returns the system time in time_t (longint) format.
time_t time(time_t *timeptr); 	
localtime()	Converts the time_t format to the tm format. Return: pointer to internal tm struct.
struct tm *localtime(time_t *ptr); 	
mktime()	Converts the tm format to the time_t format.
time_t mktime(struct tm *ntime);	
strftime()	Converts time to string. max == length of strDest string, fmt == format string, ptr == pointer to tm time. Return: strDest == output string, int value == string length / 0 - more characters then max.
size_t strftime(char *strDest, size_t max, char *fmt, struct tm *ptr); 	
difftime()	Calculates time difference between two dates. Return: number of seconds.
double difftime(time_t later, time_t earlier);	
clock()	Returns the time amount from program starting in 1/100 sec.
clock_t clock(void);	
Time format specifiers
Specifier	Description	
%a	Abbreviated weekday name.	
%A	Full weekday name.	
%b	Abbreviated month name.	
%B	Full month name.	
%c	Date and time representation (for example, 10:41:50 30-Jun-91).	
%d	Day of month as a decimal number 01 through 31.	
%H	The hour (24-hour clock) as a decimal number 00 through 23.	
%I	The hour (12-hour clock) as a decimal number 00 through 11.	
%j	The day of the year as a decimal number 001 through 366.	
%m	The month as a decimal number 01 through 12.	
%M	The minute as a decimal number 00 through 59.	
%p	AM or PM.	
%S	The second as a decimal number 00 through 59.	
%U	The week of the year as a decimal number 00 through 53. Sunday is considered the first day of the week.	
%w	The weekday as a decimal number 0 through 6 (Sunday = 0).	
%W	The week of the year as a decimal number 00 through 53. Monday is considered the first day of the week.	
%x	The date representation (for example, 30-Jun-91).	
%X	The time representation (for example, 10:41:50).	
%y	The year, without century, as a decimal number 00 through 99.	
%Y	The year, with century.	
%Z	The time zone name if the information is available or blank if not.	
Example:
time_t dostime;
struct tm *systime;
unsigned char texttime[80];

dostime=time(0);
systime=localtime(&dostime);
strftime(texttime,sizeof(texttime),"%a %d.%m.%Y %H:%M:%S",systime);
/* result: Sat 30.12.2001 23:59:59 */

Memory Operations
stdlib.h, malloc.h
Function	Description	
malloc()	Allocates num bytes of memory. Return: pointer to the first byte, NULL == error.
void *malloc(size_t num); 	
free()	Free the block of memory previously allocated by malloc().
void free(void *ptr); 	
memcpy()	Copy data from one memory block to the other. Return: *dest.
void *memcpy(void *dest, void *src, size_t count); 	
memchr()	Finds the first occurence of char in memory block. ch == char, count == number of bytes to be searched. Return: pointer to found char, NULL == not found.
void *memchr(void *buf, int ch, size_t count );	
calloc()	Allocates the block of memory (size * num bytes), initialize it to 0. Return: pointer to the first byte, NULL == error.
void *calloc( size_t num, size_t size );	
System Controls Routines
process.h
Function	Description	
execl()	Execute external program.	
exit()	Terminates program.	
system()	Execute the operating system command.	
inp()	Read one byte from I/O port.	
outp()	Write one byte from I/O port.	
Preprocessor
#DEFINE - Macros and Symbolic Constants
Symbolic constants
#define text1 text2
Example:
#define MAX 100   /* ";" NO SEMICOLON */
Every occurence of text1 will be replaced with text2, except if text1 is found within double quotation marks ("Text string for program output.").
ATTENTION: Be carefully about the text1, it will be replaced with text2 in whole program!
Function macros
Change texts with arguments
#define HALFOF(x) ((x)/2) 
Source code:
y = HALFOF(10); 
Is replaced by:
y = ((10)/2); 
String as a parameter :
#define OUT(x) printf(#x) /*definition - "#"== parameter will be a string*/
OUT(Hello Mom);           /* source code */
printf("Hello Mom");      /* macro conversion */
#INCLUDE - File
Includes a header file to your source code.
The angle brackets == the file is searched in the standard directory, then in the current directory.
#include <stdio.h>  
The double quotation marks == the file is searched in the source code directory.
#include "myfile.h"
Avoiding of Double Including
When you include in different program modules the same header file with a variable declaration, the compiler will generate an error - you can't declare the same variable twice. To avoid this, use inclusion guards:
#ifndef HEADER_FILE_NAME
#define HEADER_FILE_NAME
... /* whole contents of the header file */
#endif
#IF, #ELIF, #ELSE, #ENDIF, #IFDEF, #IFNDEF - Conditional Compilation
Commands structure:
#if condition_1
statement_block_1
#elif condition_2          /* optional - many*/
statement_block_2
...
#elif condition_n          /* optional */
statement_block_n
#else                      /* optional - only one */
default_statement_block
#endif                     /* required */
The condition can be almost any expression that evaluates to a constant (TRUE<>0).
Other possibility:
#if !defined(DEBUG) /* == #ifndef */
#define DEBUG
#endif

#if defined(DEBUG)  /* == #ifdef */
printf("DEBUG mode\n");
#else
printf("NON-DEBUG mode\n");
#endif
#UNDEF - Cancel #define
It cancels #define directive.
#define DEBUG 1
/* DEBUG name is valid in this section    */
#undef DEBUG
/* DEBUG name is unknown in this section  */
Predefined Macros
Macro	Description	
__DATE__	date when the source file was recompiled	
__TIME__	time when the source file was recompiled	
__FILE__	the source code file name	
__LINE__	the current line of the source code	
		
#PRAGMA - Implementation Dependent Directives
Special directives dependent on the compiler type.
Advanced Compiler Use
Modular Programming
To make an external function visible in the main program or any other module, you have to declare its prototype in the header file "*.h". This header file (C06mod1.h) has to be connected with source file with the same name "*.c" (C06mod1.c). In this source file (module==library file) are full definitions of functions and global variables initialization.
For making an external variable visible exists 2 ways:
•	Declaring the variable prototype in the header file == GLOBAL VARIABLE.
ATTENTION: You must not initialize the variable in header file (there are only prototypes, not definitions)!
If you don't want to have initialized variable, then the header file declaration is enough for using it.
If you want to initialize the variable, you have to do it on one place - best in the module connected with the header file.
•	Full defining the variable in the program module (library), and not in the header file.
In this case you have to use the special declaration in every module where you want to use variable.
char externalvar[]="EXTERNAL VAR"; /* full definition in module */
extern char externalvar[];         /* link to variable from main program */
Header file to library module - C06mod1.h:
/*---------------------------------------------------*
| C06mod1.h - Header file to the C06mod1.c - Modul 1 |
*----------------------------------------------------*/

/*--- VARIABLES PROTOTYPES DEFINITIONS ---*/

/* GLOBAL VARIABLE PROTOTYPE (== declaration), definition in C06mod1.c */
char visiblevar[]; 

/*--- FUNCTIONS PROTOTYPES DEFINITIONS ---*/

/* GLOBAL FUNCTION PROTOTYPE (== declaration), definition in C06mod1.c */
/*****************************************
* visiblefun - Echo test from modul
******************************************/
void visiblefun();

/* NO main() part - this is only header file */
Library module - C06mod1.c:
/*-----------------------------------------------------*
| C06mod1 - Modul 1 == FUNCTIONS and VARIABLES LIBRARY |
*------------------------------------------------------*/
#include <stdio.h>
#include "C06mod1.h"

/* INITIALISATION of the GLOBAL VARIABLE (prototype in the header file C06mod1.h) */
char visiblevar[]="VISIBLE VAR (visible from outside)";     

/* LOCAL VARIABLE - defined and used only inside of this module */
char invisiblevar[]="INVISIBLE VAR (visible only inside of this module)"; 

/* variable for external link (no record in header file), using in main module */
char externalvar[]="EXTERNAL VAR (no header file prototype, direct access from outside)"; 

/* GLOBAL FUNCTION - prototype in header file C06mod1.h */
/*****************************************
* visiblefun - Echo test from modul
******************************************/
void visiblefun()
{
	printf(">> Module/function inside START (C06mod1.c/visiblefun() )\n\n");
	
	printf("Visible variable   : %s\n",visiblevar);
	printf("Invisible variable : %s\n",invisiblevar);
	printf(">> Module/function inside END\n");
}

/* NO main() part - this is only function library */
Main program - C06modules.c:
/*------------------------------------------------*
|                                                 |
| C06 - C language learning - Modular programming |     
|                                                 |
*-------------------------------------------------*/
#include <stdio.h>
/* included header file with prototypes */
#include "C06mod1.h" 

/* EXTERNAL LINK to VARIABLE - variable defined and initialised in C06mod1.c module (no record in header file) */
extern char externalvar[];  

main()
{
printf(">> Main program\n");
	printf(">> Call external function C06mod1.c/visiblefun()\n");
	printf("------------------------------------------------\n");
	/* GLOBAL FUNCTION CALL - prototype in C06mod1.h, definition in C06mod1.c */
	visiblefun(); 
	printf("------------------------------------------------\n");
	printf(">> Wellcome back to the main module\n\n");

	printf("Global variables visibility :\n");
	printf("=============================\n");

    /* GLOBAL VARIABLE USING - prototype in C06mod1.h, definition in C06mod1.c */	
	printf("Visible (global) variable (through header definition) :\n    %s\n",visiblevar);

    /* EXTERNAL VARIABLE LINK USING - no prototype in header file, extern definition in C06mod1.c */
	printf("Visible variable (external definition - direct link to module) :\n    %s\n\n",externalvar);
}
Command-Line Arguments
Program calling:
program_name.exe argument1 argument2 ...
Code:
main(int argc, char *argv[])
argc - number of command-line arguments, at least 1 == called program name C08advanced.exe.
*argv[] - array of pointers to strings. argv[0]==program_name. Arguments are divided by space. If you need to pass an argument that includes a space, enclose the entire argument in double quotation marks (C:\program_name.exe smith "and jones"). 
C Overview
C Statements

Statement	Description	
if
else	if (expression)
    statement1;
else
    statement2;	
switch	switch (expression) 
{
    case const1: statement1; break;
    ...
    case constx: statementx; break;
    default:     statement;  break;
}	
for	for (init_expression;cond_expression;loop_expression)
    statement;	
break	Terminates the loop without evaluation loop_expression.	
continue	Causes a jump to the start and evaluation loop_expression.	
while	while (expression)
    statement;	
do - while	do
    statement;
while (expression);	
{ }	Block (compound statement).
{
    statement1;
    statement2;
}	
Advanced Data Types

Data type	Description	
array	int multi[2][3] = { {00,01,02}, {10,11,12} };/* INIT */	
string	unsigned char sa[]="abc";	
struct	struct type_name
{
    type variable_name1;
    type variable_name2;
} structure_variable;
struct type_name structure_variable;	
union	union type_name
{
    type variable_name1;
    type variable_name2;
} union_variable;	
bit field	struct 
{
    unsigned short      icon : 8; /* 8 bits field */
    unsigned short     color : 4;
    unsigned short underline : 1;
    unsigned short     blink : 1;
} screen;	
enum	enum type_name{ name1, name2=init_val } enum_variable;