C Basics
Quick syntax crash course in C
In C, declarations follow a pattern of type followed by a name such as:
C also requires you to end statements with the semicolon ;
int main(void)
{
//code goes here
}
Here, int is the return type (integer) main is the function name. The parameter void just says that a function does not take parameters
Declarations of variables are done in the same order
int x;
int y = 0;
int a, b, c;
a = 3;
b = 4; c = 5;
These show different ways of declaring and assigning
Some C standards might require you to declare first (pre C99, such as C89). For example
int i, n;
n = 16;
for (i = 0; i < n; i++){
//do stuff
}
But in C99 and later, you can declare it with the for loop
int n = 16;
for (int i = 0; i < n; i++){
//do stuff
}
In C, you can increment a variable with pre or post increment.
int i = 0;
bool greater = ++i == 0; //this is false, the variable is incremented first, and then compared
bool equal = i++ == 1; //this is true, the variable is compared first, and then incremented
More on for loops
For loops look quite innocuous in C, but you can do some really weird things with them that you can't in other languages, or things that are not as obvious
For example
for (int i = 0; loop_should_end(); i++){//do stuff}
Let's say the loop_should_end() function returns a bool (0 or 1). The return result decides if the loop continues or not.
Any kind of non-zero value keeps the loop going, while a 0 terminates the loop
Something that will look really wild is this
for (int i = 0; i < 16; i++, some_function()){//do stuff}
In C, you can give the third argument one other statement. The third argument (or arguments in this case) is executed after one iteration finishes
While loops and Do While loops
These are pretty simple and don't have any extras (like the for loop)
while(condition){//do stuff}
while(condition);//executes until condition is false, and it's usually used to increment something up to some sentinel value / terminator.
do{
//do stuff
}while(condition); //this semicolon is needed here.
Function, Structs and Enum Declarations
You can declare function signatures in C, like in other languages, as such:
int myfunc(int a, int b);
static int funcA(void); //visible inside its current file only
inline int funcB(void); //inline (C99+, or through compiler internals) suggests to the compiler to inline the function. It can work with the static keyword too.
int bar(void)
{
//this will not work and will throw a compiler error, because scoped_func is declared after this function
scoped_func();
}
int foo(void)
{
int arg = 0;
//function signature. This tells the compiler that there exists some function called scoped_func, and that is its signature.
void scoped_func(int a);
//this will work, because the function signature exists in this scope, even if it is forward declared
scoped_func(arg);
}
//forward function declaration
void scoped_func(int a)
{
//do stuff
}
Struct and Enum declarations are similar to each other:
struct Point{
int x;
int y;
};
struct Pointf{
//they can also be declared together
float x, y;
};
enum ColorType{
RED, //auto-increments as any other language
GREEN,
BLUE
};
enum TokenType{
BRACKET_OPEN = 55, // you can also start from an arbitrary place
BRACKET_CLOSE,
PAREN_OPEN = 60, // you can change a value and ignore the auto-increment
PAREN_CLOSE, //auto-increment resumes here
};
Preprocessor Macros
Most of the time, you will use #include and #define macros
The former will paste a file into the current file, and the latter will declare some code to some name
For example:
#include "myfile.h" //this will literally paste the contents of myfile.h into the current file
#include <stdio.h> //the angle-bracket is used to tell the compiler that the target directory is in /usr/includes ( for Linux )
#define MAX_LEN 64 //wherever MAX_LEN is used, it will be 64
static int array_a[MAX_LEN]; //it will paste 64 in here
static float array_b[MAX_LEN]; //it will paste 64 in here
Any code works in a #define such as:
#include "myfile.h" //this will literally paste the contents of myfile.h into the current file
#include <stdio.h> //the angle-brackets tell the compiler to search system include paths (like /usr/include on Linux)
#define min(a, b) ((a) < (b) ? (a) : (b)) //ternary operator "?" works like in other languages
#define max(a, b) ((a) > (b) ? (a) : (b))
int main(void)
{
int a, b;
float i, j;
a = 3; b = 5;
i = 5.5; j = 6.5;
float resultf = max(i, j); //this will result in j
int resulti = min(a, b); //this will result in i
}
To put multiple lines of code in a #define you do as follows:
//notice the backslash "\" at the end. Also, there cannot be any spaces
#define FIELDS \
float x, y;\
int width, height;
//Just as an example, this will paste in the text, line by line, as you wrote it.
struct Rectangle{
FIELDS
};
That's enough introduction to the syntax and declarations. Next, I'll go into a very important first step: String Parsing and Memory Management