This document is intended to be a quick reference to the C programming language. Refer to the bibliography for further reading.
Data type declaration, number of bits, and range:
ASCII character data:
Integer data:
- char
- 8 bits: -128 to 127
- signed char
- 8 bits: -128 to 127
- unsigned char
- 8 bits: 0 to 255
Floating point data:
- int
- 16 bits: -32768 to 32768
- unsigned int
- 16 bits: 0 to 65535
- short int
- 16 bits: -32768 to 32767
- unsigned short int
- 16 bits: 0 to 65535
- long int
- 32 bits: -2147483648 to 2147483647
- unsigned long int
- 32 bits: 0 to 4294967295
Other data types:
- float
- 32 bits: 3.4E-38 to 3.4E+38
- double
- 64 bits: 1.7E-308 to 1.7E+308
- long double
- 80 bits: 3.4E-4932 to 3.4E+4932
The bits and range values above are the most common implementations. Actual size will vary depending on your machine and compiler. The void data type is used to turn functions into subroutines. Use the * before a variable name to declare a pointer.
- void
- 0 bits: no range
- (pointer)
- variable size: memory address
( type ) expression
Forces the result of expression to be of data type type.
Operator precedence summary (highest to lowest):
() [ ] -> .
! ~ ++ -- - (type cast) * & sizeof
* /
%
<< >>
< <= > >=
==
!=
&
^
|
&&
||
?
= += -= *= /= %= >>=
<<= &= |= ^=
,
Symbol Meanings:
+ addition ( x + y )
++ post-increment ( x++ ) or pre-increment (++x )
unary operator
+= self-addition ( x += 3 is equivalent to x = x + 3 )
Symbol Meanings:
- subtraction ( x - y ) or unary minus ( -x )
-- post-decrement ( x++ ) or
pre-decrement ( ++x ) unary operator
-= self-addition ( x += 3 is equivalent
to x = x + 3 )
Symbol Meanings:
* multiply ( x * y )
*= self multiplication ( x *= y is equivalent to x =
x * y )
Symbol Meanings:
/ divide (x / y)
/= self-division (x /= 3 is equivalent to x = x / 3)
Symbol Meanings:
% modulus (x % y)
%= self modulus ( x %= y is equivalent to x = x % y )
Modulus produces the remainder of an integer division ( 5 % 3 = 2 ). The modulus operator may only be used with integer variables.
Symbol Meanings:
& bitwise AND
&= self bitwise AND ( x &= y is equivalent to x
= x & y )
| bitwise OR
|= self bitwise OR ( x |= y is equivalent to x
= x | y )
^ bitwise XOR
^= self bitwise XOR ( x ^= y is equivalent to x =
x ^ y )
~ one's compliment (inverse) unary operator
Bitwise operators may only be used with char and int data types. These should not be confused with the logical comparison operators.
Symbol Meanings:
<< shift left, fill right side with 0
<<= self shift left ( x
<<= y is equivalent to x = x << y )
>> shift right, fill
left side with 0
>>= self shift left ( x >>= y is equivalent to x
= x >> y )
variable <<
integer-expression
variable >>
integer-expression
Shift variable left (or right) integer-expression number of bits. Shift operators may only be used with char and int data types.
Symbol Meanings:
> greater than
>= greater than or equal
< less than
<=
less than or equal
== equal
!= not equal
Relational operators evaluate to 0 for false, and non-zero (usually 1) for true.
Symbol Meanings:
! NOT
&& AND
|| OR
Logical comparison operators evaluate to zero for false, and non-zero (usually 1) for true. These should not be confused with the bitwise arithmetic operators.
Symbol Meaning:
= equals
variable = expression;
variable1 =
variable2 = ... = variableN = expression;
Symbol Meanings:
* value unary operator
& address unary operator
*variable returns value of
variable
&variable returns address where
variable is stored
expression1, expression2;
The comma (,) operator is used to separate expressions. It has the lowest precedence of all C operators. It is mainly used in for loops when more than one loop control variable is used.
Example:
for( i = 0, j = 100; i<j ; i++, j-- ) {...}
Code Meanings:
\b backspace
\f form feed
\n new line
\r carriage return
\t
horizontal tab
\" double quote
\' single quote
\0 null
\\
backslash
\v vertical tab
\a bell
\N octal constant (where N is an
octal constant)
\xN hexadecimal constant (where N is a hexadecimal constant)
%[- ][min-field-width][.][precision]format-specifier
%c character (char) variable
%s string variable
%d signed decimal
integer (int) variable
%i signed decimal integer (int) variable
%f signed
decimal floating point (float) variable
%e scientific notation (with
lowercase e)
%E scientific notation (with uppercase E)
%g uses %f or %e,
whichever is shorter
%G uses %f or %E, whichever is shorter
%o unsigned
octal
%x unsigned lowercase hexadecimal numbers
%X unsigned uppercase
hexadecimal numbers
%p displays a pointer
%n pointer to integer value
loaded with number of characters printed so far
%% percent sign
u unsigned
decimal integer variables (used in combination with other printing codes)
h
used with %x and %X to print short integers
l used with %x and %X to print
long integers
l used with %e and %E to print long floats
L used with %e
and %E to print long double floats
- used right after % sign to left justify
output (%-d)
if ( expression ) statement;
if ( expression ) {
statement1;}
statement2;
...
statementN;
If expression is non-zero, then statement(s) are executed.
if ( expression ) statement1;
else
statement2;
If expression is non-zero, then statment1 is executed. If expression is zero, then statment2 is executed.
if ( expression ) {
statementA1;
}
statementA2;
...
statementAN;
else {
statmentB1;
}
statmentB2;
...
statementBN;
If expression is non-zero, then statmentA(s) are executed. If expression is zero, then statmentB(s) are executed.
variable = expression1 ? expression2 :
expression3;
expression1 ? expression2 :
expression3;
If expression1 is non-zero (true), expression2 is evaluated. If expression1 is zero (false), expression3 is evaluated.
switch ( variable ) {
case constant1:
}
statements;
case
constant2:
break; statements;
default:
break;statements;
The switch statement works only with character or integer data types and can only test for equality ( variable == constant ). The break statements are optional. When a match is found, statements are executed (including statements in subsequent case blocks) until a break statement or the end of the switch statement is reached. The optional default statement sequence is performed if no matches are found. If all matches fail, and there is no default statement, no action takes place.
for ( initialization ; conditional-test ; increment ) statement;
for ( initialization ; conditional-test ; increment ) {
statment1;}
statment2;
...
statementN;
The initialization portion of the for loop may be left empty if the variable
is initialized before the for loop:
i = 1;
The following is an endless loop, I don't suggest that
you use it:
for ( ; i < 100 ; i++) statement;
for ( ; ; ) {
statement1;
}
statment2;
...
statementN;
while ( expression ) statement;
while ( expression ) {
statment1;}
statment2;
...
statementN;
The contents of the loop are executed only if expression is true.
do statement while ( expression );
do {
statement1;} while ( expression );
statement2;
...
statementN;
The contents of the loop are executed at least once, and then again until expression is no longer true.
break;
The break statement is used to exit looping constructs.
continue;
The continue statement forces a loop to begin its next iteration immediately, skipping any code between the continue statement and the end of the loop.
label:
goto label;
type variable[size] = { values };
The optional "= { values }" portion of the declaration initializes the array values. The size component of the declaration may be omitted if the array is initialized. A string is a one-dimensional array of characters with the null character (\0) as its last element. Null termination is handled automatically by the compiler when strings are enclosed in double quotes ("). An array of characters which will be used as a string must accommodate this null termination by being declared at least one unit longer than the longest string it is intended to hold.
Examples:
int i[15];
float f[3] = { 1.2, 1.0, 102.45 };
char[3] = { 'A', 'B',
'e' };
char[5] = "tree";
int z[ ] = {1, 4, -4, 4, 6, 132 };
type variable[size1][size2]...[sizeN] = { values };
Again, the optional "= { values }" portion of the declaration initializes the array values. The left most size component of the declaration may be omitted if the array is initialized. The right most index changes the fastest when initializing a multidimensional array. A two-dimensional array of characters is used to hold an array of strings.
Examples:
unsigned long stuff[45][10][3];
int i[3][4] = {
1, 5, 8, -3,};
2, 7, -1, 45,
100, 45, 6, 0
char names[10][40];
float z[ ][2] = {
1.2, -4.5,};
12.0, 3.1,
1.1, 2.2
int x[2][2][4] = {
1, 2, 3, 4,};
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16
see Pointer Arrays.
type name : size;
type ::= < signed | unsigned >
The type argument is either signed or unsigned.
type *variable;
A pointer is a variable that hold the memory address of another object of a given type. The * pointer operator returns value at the address contained in the pointer (ie: pointed to by the pointer). The & operator returns the memory address contained in the pointer.
Example:
int *i, j;/* declare i as pointer to int, and j as an int */
i =
&j; /* put address of variable j into pointer i */
*i = 100; /* now this
is the same as saying j = 100; */
Only the +, ++, -, and -- arithmetic operators may be used on pointers.
Example:
float *p, q; /* declare p as pointer to float, q as float*/
(*p)++; /*
increment the float value pointed to by p */
*(p+1); /* value of the next
float variable */
*p++; /* increment pointer to next float variable */
Remember that when you compare pointers, compare either the values they point to or the pointer addresses, but don't mix addresses and values.
type *variable[ size ];
Arrays may also contain pointers.
Examples:
int *p[5], q; /* p as array of 5 pointers to int, q as int */
char *t;
/* declare t as pointer to a char (ie: a string) */
*t = "This is a string";
/* assign a value to string t */
q = 67; /* assign a value to integer q
*/
p[3] = &q; /* assign q's address to fourth value in array p */
type **variable;
A pointer can point to another pointer. This is known as multiple indirection. There can be any number of pointers to pointers in the indirection. Include one asterisk (*) in the declaration for each pointer in the indirection.
Example:
int **x;
char ***c;
type ( *variable ) ( parameter-list );
The type must be the same type as the return type of the function to be pointed to. The parameter-list must be identical to the parameter list of the function to be pointed to.
Example:
int sum(int a, int b);
int result;
int (*p) (int x, int y);
p =
sum;
result = (*p)(10, 20);
You can also set up an array of function pointers which can be used much the same way the case statement is used.
Example:
int sum( int a, int b );
int subtract( int a, int b );
int mul( int
a, int b );
int div( int a, int b );
int ( *p[4] ) ( int a, int b ) = { sum, subtract, div, mul };
void main() {
int result,x,y, operation;}
operation = 3;
result = ( *p[operation] ) ( 10, 3 );
Structures allow related data (possibly of different types) to be grouped together.
struct tag-name {
type1 field-name1;
} variable-list;
type2
field-name2;
...
typeN field-nameN;
After a structure format is declared, other variables may use the structure type as follows:
struct tag-name variable-list;
Data in structures not declared as pointers is accessed using the dot operator:
variable.field-name
When using pointers to structures, you must use the arrow operator instead of the dot operator:
pointer-variable->field-name
Unions allow several variables (possibly of different types) to share the same memory location.
union tag-name {
type1 element1;
} variable-list;
type2
element2;
...
typeN elementN;
After the union format is declared, other variables may use the union type as follows:
union tag-name variable-list;
Data in unions not declared as pointers is accessed using the dot operator:
variable.field-name
When using pointers to unions, you must use the arrow operator instead of the dot operator:
pointer-variable->field-name
type fn-name(type param1, type
param2,..., type paramN) {
statement1;
}
statement2;
...
statementN;
The old way of declaring functions defined parameter types outside the argument list:
type fn-name( param1, param2,...,
paramN )
type parameter1;
type
parameter2;
...
type parameterN;
{
statement1;
}
statement2;
...
statementN;
The type declaration before the function name specifies the data type returned by the function. If there is no type declaration, the compiler assumes the return type to be an integer. If a function does not return a value, its type is declared as void. The type declaration before the parameters specifies what type of data is passed to the function.
A function must be declared for the compiler by specifying its type and name before it is used. This is done by either of the following methods:
type fn-name();
type fn-name(type
param1, type param2,..., type paramN);
type main( int argc, char *argv[ ]) ;
{
statements;
}
type main ( argc, *argc[ ] )
int argc;
char *argc[ ];
{
statements;}
The main function is the only required function in a C program. Like any other function, main may return a value (to the operating system) or may receive command line arguments (from the operating system). The function main receives the following two arguments from the operating system: argc and argv. Argc is an integer containing a count of the number of command line arguments used when invoking the C program (including the name of the program itself). Argv is an array of character pointers. Each element of argv is one command line argument string, starting with argv[0] which is the name of the command line program. Since the argv array starts with index 0, the index to the last element in argv is argc-1.
Example:
void main( int argc, char *argv[ ] )
{
statements;
}
Parameters may be passed by either value or reference. If a parameter is passed by value, is treated as a local variable. If a parameter is passed by reference, it is treated as a global value. Arrays can only be passed to functions by reference.
Passing values by reference allows functions to be used as subroutines are used in other languages.
return;
return value;
return( expression );
The return statement sends program control back to the point at which the subroutine was called, optionally returning value, or the result of evaluating expression. If a function does not have a return statement, a return is performed when the closing brace of the function is encountered.
See Function Pointers in the Pointers section.
Symbol Meanings:
/* start comment
*/ end comment
Examples:
/* comment */
/* comment1
comment2 */
The following comment form is also used by some compilers (especially C++ compilers):
Symbol Meaning:
// begin comment
<eoln> end comment (end of line)
Example:
// comment
#include "filename"
#include <filename>
Using quotes ("") causes the compiler to search for the include file in the current working directory first, then other directories in the path. Using angle brackets (<>) causes the compiler to search for the include file in default directories first. The filename usually uses the .h extension which stands for "header file".
#define macro-name macro
Example:
#define SUM(i, j) i+j
causes the statement:
x = SUM(3,
r);
to be expanded to:
x = 3 + r;
Example:
#define TWENTY 20
causes the statement:
x =
TWENTY;
to be expanded to:
x = 20;
If the #define operator is to be used with the #ifdef or #ifndef operators, string is not necessary:
#define macro-name
Example:
#define DEBUG
#undef macro-name
#variable
variable ## variable
The # operator turns the argument of a function-like macro into a quoted string.
Example:
#define MKSTR(str) #str
causes the statement:
printf("%s
is %d\n", MKSTR(value), value);
to be expanded to:
printf("%s is
%d\n", "value", value);
The ## operator concatenates two identifiers.
Example:
#define OUTPUT(x) printf("%d %d\n", x ## 1, x ## _old)
causes the
statement:
output(a);
to be expanded to:
printf("%d %d\n",
a1, a_old);
sizeof ( datatype );
int sizeof variable;
The sizeof operator is a compile-time operator that returns the size (in bytes) of a data type or variable (used in fread and fwrite functions).
Storage class specifiers affect how a variable is stored.
auto type variable;
extern type
variable;
register type variable;
static type
variable = value;
const type variable = value;
volatile type
variable;
enum tag-name { enumeration-list } variable-list;
Once an enumeration list type is declared, it can be used to declare other variables:
enum tag-name variable;
typedef old-name new-name;
For example:
typedef signed char smallint;
#if constant-expression
statement-sequence
#endif
#if constant-expression
statement-sequence1
#else
statement-sequence2
#endif
#if constant-expression1
statement-sequence1
#elif
constant-expression2
statement-sequence2
#elif
constant-expression3
statement-sequence3
...
#endif
#ifdef macro-name
statement-sequence
#endif
#ifndef macro-name
statement-sequence
#endif
#error message
Causes the compiler to stop compilation and display message along with other compiler-dependent information.
#line line-number "filename"
Sets the compiler's line number and file name for the next line of source code to line- number and filename. This is apparently used to link several source code files together in one compile.
#pragma instructions
Defines other preprocessing instructions to be give to the compiler. The ANSI standard does not specify any #pragma directives.
The __LINE__ macro contains an integer value that is equivalent to the line number of the source code currently being compiled.
The __FILE__ macro contains a string that is the name of the file currently being compiled.
The __DATE__ macro contains a string that holds the current system date. The string has the genera form:
month/day/year
The __TIME__ macro contains a string that holds the time the compilation of a program began. The string has the general form:
hour:minute:second
The __STDC__ macro contains the value 1 if the compiler conforms to the ANSI standard.
/* comments */
#include <filename1>
#include
<filename2>
...
#include <filenameN>
extern type variable;
type fn-name1(type param1, type param2,...,
type paramN);
type fn-name2(type param1,
type param2,..., type paramN);
...
type
fn-nameN(type param1, type param2,..., type
paramN);
void main( int argc; char *argv[ ] )
{
variable-declarations;}
statements;
type fn-name1(type param1, type param2,...,
type paramN)
{
local-variable-declarations;}
statements;
type fn-name2(type param1, type param2,...,
type paramN)
{
local-variable-declarations;}
statements;
local-variable-declarations;}
statements;
Standard input and output streams may be specified for any of the standard file access functions. The stdin, stdout, and stderr streams are FILE pointers and may be used with any function that uses a variable of type FILE *. These data streams can be redirected by operating systems that support redirection.
All file functions described here require the stdio.h header file.
Function: Open a file named filename
Declaration: FILE
*fopen( char *filename, char *mode );
Returns:
NULL if an error occurs
Description: The mode argument must be one
of the following strings:
Mode Meanings:
- r
- open a text file for reading
- w
- create a text file for writing
- a
- append text to a text file
- rb
- open a binary file for writing
- wb
- create a binary file for writing
- ab
- append to a binary file
- r+
- open a text file for read/write
- w+
- create a text file for read/write
- a+
- append or create a text file for read/write
- r+b
- open a binary file for read/write
- w+b
- create a binary file for read/write
- a+b
- append a binary file for read/write
Function: Close a file
Declaration: int fclose( FILE
*filepointer );
Returns: EOF if an error occurs
Function: Flush a file's disk buffer
Declaration: int fflush( FILE
*filepointer );
Returns: 0 if successful, EOF if an error occurs
Function: Check if end of file reached
Declaration: int feof( FILE
*filepointer );
Returns: 0 if not at EOF, non-0 if at EOF
Function: Check for file error
Declaration: int ferror( FILE
*filepointer );
Returns: 0 if no error, non-0 if an error has
occurred
Function: Erase a file
Declaration: int remove( char
*filename );
Returns: 0 if successful, non-0 if an error
occurs
Function: Reset location of a file position indicator to beginning of
file
Declaration: void rewind( FILE *filepointer
);
Returns: nothing
Function: Determine location of a file position indicator
Declaration:
long ftell( FILE *filepointer );
Returns: -1 if an error
occurs, position of pointer if successful
Function: Set location of file position indicator (for random
access)
Declaration: int fseek( FILE *filepointer, long
offset, int origin );
Returns: non-0 if an error
occurs, 0 if successful
Description: the origin argument must be
one of the following macros:
Origin Argument Meanings:
Function: Write value to a file
Declaration: int fputc( int
value, FILE *filepointer )
Returns: EOF if an
error occurs
Function: Write a string to a file
Declaration: int fputs( char
*string, FILE *filepointer );
Returns: EOF if an
error occurs, non-negative if successful
Function: Write formatted text to a file
Declaration: int fprintf(
FILE *filepointer, char *control-string, ...
);
Returns:
Function: Write count number of size byte long binary
data objects to a file from buffer
Declaration: size_t
fwrite(void *buffer, size_t size, size_t count,
FILE *filepointer);
Returns: a count of the number of objects
written (see sizeof operator)
Function: Read from a file
Declaration: int fgetc( FILE
*filepointer );
Returns: EOF if an error occurs
Function: Read count-1 characters from a file into
string
Declaration: char *fgets(char *string, int
count, FILE *filepointer);
Returns: NULL if an
error occurs, null terminated string if successful
Function: Read formatted text from a file
Declaration: int fscanf(FILE
*filepointer, char *control-string, ...);
Returns:
Function: Read count number of size byte long binary
data objects from a file into buffer
Declaration: size_t
fread(void *buffer, size_t size, size_t count,
FILE *filepointer);
Returns: a count of the number of object
actually read (see sizeof operator)
The memory allocation functions described here require the stdlib.h header file.
Function: Allocate numbytes bytes of memory
Declaration:
void *malloc ( size_t numbytes );
Returns: pointer to the
start of allocated memory if successful, NULL if an error occurs
Function: Allocate count * size bytes of
memory
Declaration: void *calloc ( size_t count, size_t
size );
Returns: pointer to the start of allocated memory if
successful, NULL if an error occurs
Function: Free memory allocated with the malloc or calloc
functions
Prototype: void free ( *pointer );
Returns:
nothing
Function: Change the size of allocated memory
Declaration: void
*realloc ( void *pointer, size_t numbytes
);
Returns: pointer to the start of allocated memory if successful, NULL
if an error occurs (the original block is freed)
The termination functions described here require the stdlib.h header file.
Function: Exit a program
Prototype: void exit( int status
);
Returns: nothing (closes files), passes status to
operating system
Function: Abort a program
Prototype: void abort( void
);
Returns: nothing (may not close files)
The random number functions described here require the stdlib.h header file.
Function: Generate a pseudo-random number
Prototype: int rand( void
);
Returns: integer between 0 and RAND_MAX (32767 in ANSI standard)
Function: Set pseudo-random number generator seed
Prototype: void
srand( unsigned seed );
Returns: nothing
auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while
asm _cs _ds _es _ss cdecl far huge interrupt near pascal
Schildt, Herbert. "Teach Yourself C" Osborne McGraw-Hill, 1990.
Purdum, Jack. "C Programming Guide" Second Edition, Que Corporation, 1985