We will be using the gcc
compiler throughout.
The most basic code-base for a program written in C is shown below, with annotations:
To compile and run the program, use the following commands in a terminal
Here is a quick run-down of the syntax:
stdio.h
header file in all your programs.//
for single-line, and /* ... */
for multi-line.The standard types of variables are what you should expect, listed below, except there is no string
variable type.
char
- a Characterint
- an Integer (up to ± 32767 on a 32-bit system)long int
- a larger Integer (up to ± 2147483647)float
- a Floating Point Numberdouble
- a Floating Point Number with greater precisionTo declare a variable, we use the following syntax
For strings, we use a character array whose length is one more than te length of the word. This takes into account the newline at the end of the string.
Variables declared outside any functions are called global variables and can be accessed by any function in the program. Variables declared inside a function are called local variables and are destroyed once the function exits. A static variable is a local variable but it’s value is preserved on exit of a function, and is available for use when the function is next called.
Constant variables are declared in a similar way
Alternatively, you can use the C-proprocessor directive #define
:
Some standard library functions require a conversion specification for different types of variables.
One function which uses these is printf
Special characters can also be used, such as \t
and \n
, to indicate a tab or newline, respectively.
For integers, floats and doubles you can format the output.
The .
allows for precision. The number 10
puts 0005
over 10 spaces so that the number 5
is on the tenth spacing.
To capture input, from a keyboard for example, we use the fgets(str,sizeof(str),stdin)
function, which takes three parameters: str
is a character array, sizeof(str)
is the maximum number of characters to be read (plus one for the newline), and stdin
the source of the input (keyboard).
fgets()
returns the whole string. To remove the newline character use
To convert the text read in via fgets()
we use the function sscanf(line,"%d %d %d",&num1,&num2,&num3)
, where line
is the input from fgets()
, and &num1
, &num2
, &num3
are points to already initiated integers.
To read input from a file, rather than a keyboard, just provide the filename in fgets()
There are several string specific functions which are good to know:
The usual mathematical operators are present: +
, -
, /
, *
, %
. Note (expecially when using division) that if both operands are integers, then the output will be an integer.
The comparision operators are ==
, !=
, <
, >
, <=
, >=
, which return 0
or 1
. Note that when comparing two real numbers it is usually better to use a tolerance:
Boolean operators are &&
, ||
, !
.
It is often useful to know the order of precedence when using many operators in one statement.
Statement block are groups of code within a single set of curly braces { }
.
Conditional blocks are similar to other programming languages:
The usual loops are present:
The keywords break
and continue
can be used in loops.
Just like a character array, we can have arrays which hold other types of variables, such as an integer array: int int_arr[]
. Arrays are zero-index-based. Be careful not to address array elements outside of the declared array, as this will result in errors. Writing to an index outside of the declared array means writing to a random memory slot, and may cause weird things to happen!
Multi-dimensional arrays are declared such as int mul_arr[][]
. Since memory is linearly addressable, matrices in C are stored in row-major order.
All functions must be declared, known as a function prototype, before the main()
function. The general syntax is as follows
The return_type
of a function is the variable type that the function returns. If a function doesn’t return anything, set return_type
to void
.
Variables can be accessed, as before, by name. When variables are passed to functions as such, in fact, only its value is passed through as a local variable. Any changes made to an argument will not affect the original variable. If you wish to change the original variable by a function, you will need to pass through a variable pointer.
Pointers are objects that points to a memory address of another object. Pointers must be declared (since they are variables that store memory addresses).
To recall the memory address of a variable, we use the ampersand operator.
To get the content of a memory address given by a pointer, we use an asterisk.
The name of an array is the same as a pointer to that array. So *array
is the same as array[0]
, and *(array+1)
is the same as array[1]
, etc.
Pointers allows us to allocate memory for a program at runtime, rather than compile time - this is called dynamic memory allocation. malloc
stands for memory allocation and is a standard library function. It’s prototype is
malloc
returns a generic pointer, a pointer which points to any type of object. When malloc
runs out of memory space, it returns a null pointer. Hence, we need to check for this condition at each malloc
call.
calloc
and realloc
are other dynamic memory allocation functions.
It is best to free up the memory. To do so, use the free
function, and then set the relevant pointer to NULL
.
Structures allow you to organise related objects. These can be variables or functions, etc. The definition of a structure should be at the top of the program.
When passing a structure to a function, we usually pass a pointer to the structure, and use the arrow symbol ->
to access the contents of a pointer.
As well as the standard input/output library, we have others. Most often, you will want to use mathematical functions. These are included in the math library.
To compile a program, we now need to use the -lm
parameter so that the compiler knows to look for the libm.*.so
library in the directory /lib/
.