Created: 2023-01-10 15:58
Status: #concept
Subject: Programming
Tags: Linux Memory Address Pointer Operating System

C

A low-level Programming Language created by Dennis Ritchie at Bell Labs between 1972 and 1973 to construct utilities running on Unix.

Basic Anatomy of a C Program

We declare a main Function which is automatically invoked when we run a compiled C program like ./program.exe.

  • ./ means we check the . current Path's / directory for a file named program.exe.

int main(void)
{
	statements;
}

Directives

They are program editing commands (Preprocessor commands) that modify the program contents prior to compilation into an executable.

#include <stdio.h>
/* This directive states that all the code in <stdio.h> is to be "included" or concatenated into the program before it is compiled */

Statements

They are commands that are performed when the program is run and are parsed by the compiler via the program's tokens.

#include <stdio.h>

int main(void)
{
    printf("To C, or not to C: that is the question.\n");
    return 0;
}

The main() Entry Point Function

the main function's return type is an Integer to indicate the status code of the program: 0 for success, 1 for an error - used in conditional program chaining or Bash scripting.

Standard Libraries

Standard libraries extend the capabilities of programming languages by including Macro Definition or Function declarations.

  • they are grouped into functional domains.

Reserved Words

We cannot use these Identifiers in C because they mean something else to the compiler.

  • standard library functions are NOT reserved keywords because they can be used as Variables when the library is not included by #include.

C Reserved Keywords.png

Type Conversion System

Splitting Programs into Modules

We typically write our source code into .c files while data structure declarations and Function Prototypes go into .h files.

  • we compile our code with gcc [...FILES] -o [OUTPUT_NAME].
  • if we have more source code dependencies, we use Makefiles and the make command.

#include <filename> // searches /lib/gcc/x86_64-linux-gnu/11/include
#include "filename" // searches the current working directory

Example

/* extern.h */
void printFoo(void);

extern int i; // used to type check or allow the source code to access 'i'
/* extern.c */
#include <stdio.h>
#include "extern.h"

int i = 3; // original variable declaration

void printFoo(void)
{
    printf("Foo!");
}
/* main.c */
#include <stdio.h>
#include "extern.h"

int main(void)
{
    printf("%d\n", i); // using 'i' without any declaration through 'extern int i'
    printFoo();
}
gcc main.c extern.c -o main
./main # runs the compiled program

Using Header Guards in C

When we include the same file twice, a compilation error will occur.

  • we can use Macro Definitions and compilation directives to conditionally compile code.

Include Header Guards C.png

Reading Complex Declarations in C

There are 2 rules which comprise the Spiral Method for reading C declarations.

  1. First, identify the Identifier of the thing being declared and parse it going outwards.
  2. When there's a choice between * or []/(), prefer the latter first.

int *ap[10]; // an array containing 10 elements, whose types are int pointers

void (*pf)(int); // pf is a pointer to a function, with an int parameter, returning void

File Handling

References