This English version is an adapted summary of my Turkish lecture notes on C programming with Borland Turbo C, a classic DOS-era compiler. Examples are written in standard C; Turbo C-specific functions such as clrscr() and getch() from conio.h are not available in modern compilers. The full notes, with all the original examples, are in the Turkish version.

Basic concepts

  • Program: code written to make a computer carry out a sequence of operations for a specific purpose.
  • Data: raw, unprocessed information entered into a computer.

Programming languages range from machine language, which the processor runs directly as 0s and 1s, to symbolic languages, which must be translated into machine code. Among the latter, low-level languages such as assembly are very close to machine code, while high-level languages such as C are easy for people to write but always need a compiler or interpreter.

Structure of a C program

A C program generally consists of preprocessor directives (#include, #define), global variable declarations, function prototypes, the main() function and other function definitions. Every statement ends with a semicolon, and blocks are enclosed in curly braces.

#include <stdio.h>           /* preprocessor directive */

int square(int x);           /* function prototype */

int main(void)               /* main function */
{                            /* start of function */
    int n = 5;
    printf("%d squared is %d\n", n, square(n));
    return 0;                /* end of statement */
}                            /* end of function */

int square(int x) { return x * x; }

Output with printf

printf prints formatted output. Common format specifiers: %d (signed integer), %u (unsigned integer), %ld (long), %f (floating point), %lf (double), %e (exponential), %c (single character) and %s (string). Width and precision can be set, e.g. %8.2f. Escape sequences include \n (new line), \t (tab), \a (beep), \\ (backslash) and \" (double quote).

Input with scanf

scanf reads formatted input using the same specifiers. Variables are passed by address with & (except strings). When reading several values, they can be separated by spaces or by pressing Enter after each one.

int age;
float height;
printf("Age and height: ");
scanf("%d %f", &age, &height);

Operators

  • Arithmetic: + - * / and % (remainder of integer division).
  • Increment/decrement: ++ and --, in prefix or postfix form.
  • Compound assignment: += -= *= /= %= and their bitwise counterparts.
  • Bitwise: & (AND), | (OR, often used to set bits to 1), ^ (XOR), ~ (NOT), << and >> (shift left/right; shifting right by one divides by two, rounding down).
  • Relational: == != < > <= >=.
  • Logical: && (true only if both are true), || (true if at least one is true) and ! (not).

In mixed expressions, C converts operands to the “wider” type (for example, int + double gives a double), and the result is then converted to the type of the variable it is assigned to.

Control statements: if and switch

if (score >= 50)
    printf("Passed\n");
else
    printf("Failed\n");

switch (choice) {
    case 1:  printf("Add\n");      break;
    case 2:  printf("Subtract\n"); break;
    default: printf("Invalid choice\n");
}

switch works like an if-else if chain on a single integer expression and is often easier to read. Remember the break after each case.

Loops

C has three loops: for, while (condition checked at the start) and do-while (condition checked at the end, so the body runs at least once). break leaves the loop immediately; continue skips to the next iteration.

for (i = 1; i <= 10; i++) {
    if (i % 2 == 0) continue;   /* skip even numbers */
    if (i > 7) break;           /* stop after 7 */
    printf("%d ", i);
}

Arrays

An array is a sequence of elements of the same type stored next to each other in memory. Indexing starts at 0, so int number[5] has elements number[0] to number[4]. Two-dimensional arrays such as int m[3][4] have 3 rows and 4 columns, and arrays can have more dimensions. A string is simply an array of characters ending with '\0': char message[7] takes 7 bytes of memory.

Pointers

A pointer is a variable that holds the memory address of another variable. &x gives the address of x, and *p gives the value stored at the address held in p. Pointers make it possible to access any memory area, pass values between functions (including returning more than one value), read command-line parameters, use dynamic memory and perform advanced operations on arrays and strings. An array name is itself a pointer to its first element, so a[i] and *(a + i) are the same.

void swap(int *a, int *b) {
    int t = *a;
    *a = *b;
    *b = t;
}
/* call: swap(&x, &y); */

Files

A file is a collection of related records stored on disk. C distinguishes between text files, which store data as readable characters, and binary files, which store data in its raw memory form. Typical file operations are entering, searching, editing, deleting, adding and listing records.

Files are opened with fopen using a mode: "w" (write; an existing file is erased), "r" (read only), "a" (append), "w+", "r+" and "a+" (read and write combinations), with "t" or "b" for text or binary (text is the default). fclose closes a file, and feof tells you whether the end of the file has been reached.

#include <stdio.h>

int main(void)
{
    FILE *f;
    int i, n;

    f = fopen("numbers.txt", "a");      /* add two numbers */
    for (i = 1; i <= 2; i++) {
        printf("Number %d: ", i);
        scanf("%d", &n);
        fprintf(f, "%d\n", n);
    }
    fclose(f);

    f = fopen("numbers.txt", "r");      /* list all numbers */
    while (fscanf(f, "%d", &n) != EOF)
        printf("%d ", n);
    fclose(f);
    return 0;
}