How to understand C as a JavaScript Developer

As a Computer Science freshmen at NTU, I have to transit from my hobby of writing JavaScript to writing C. Here are some notes.

How to understand C as a JavaScript Developer

As a Computer Science freshmen at NTU, I have to transit from my hobby of writing JavaScript to writing C. Here are some notes.

Disclaimer: I have done C++ in the past before, so this is more of a refresher for me 🤷‍♂️.

Note: I have not started studying structs and data structures, so a part 2 maybe?

How does a C program build?

For some context: Compiling a C program happens in 4 steps:

  1. Preprocessing
    The usual first step, removing comments, importing stuff from headers.
  2. Compiling
    Taking the result from step 1 and turning it into assembly for the targeted processor/platform.
  3. Assemble
    The assembler turns the assembly code into binary (this is really cool if you don't have to take it for exams, understanding assembly made me appreciate types and other features programming languages).
    Read more at tutorialspoint.com
  4. Linking
    Links library functions

Hello world

Now that we got the boring stuff out of the way, lets start on the syntax.

We will try to write the following JavaScript hello world program in C

console.log("hello world")

And now, in C

#include <stdio.h>

int main () {
  printf("hello world");
  return 0;
}

#include <stdio.h>
directive
We are importing the standard input/output library, that allows us to print and display stuff to the command line.

int main ()
function
C will start its execution from its main function. Since C is a static type language, Every variable and function in C will have a type if necessarily. Note: the void keyword exist to satisfy functions that has no return value.

printf("hello world");
displaying strings

return 0;
Since the main function is an integer type, we need to return an integer value.

Types

In JavaScript, we mainly use 1 type of number type: number. That is a floating point value expressed in 64 bits. Which means, 64 1s and 0s are needed to store a single number in JavaScript. In a high level environment like NodeJS or the browser, that is not a problem. But for a relatively low-level language like C, it is a huge problem. Which is why, C has many types to represent numbers; from 2 bit integers to 128 bits floating points.

unsigned short int
An unsigned number in C means that it can only be positive. A short int means the variable is expressed in 16 bits (or 2 bytes) in memory.
A use-case for this will be a increment counter.

long long int
This type represents a signed integer (can be negative) that takes up 64 bits in memory.

We often run JavaScript in an environment where memory and CPU resources are not the main concern, thus we don't think much when initializing variables (and also we can't because the browser does that for us).

Because of the nature of C, we often have to run C code in extreme conditions where the memory and CPU resources might be a stretch. Thus, using the correct type for the scenario can be crucial.

Type Casting

Type Casting in C is necessarily because the operations is heavily dependent on the types. E.g. When you operate on 2 integers, the result will be an integer.

For example:

int four = 4;
int three = 3;
double foo = four/three;

// int/int is int 
// foo = 1.000000

For the result to be a double, one of the 2 operands have to be a double. This is where Explicit Type Conversion comes in. Examine the new snippet:

int four = 4;
int three = 3;
double foo = (double)four/three;

// double/int is double 
// foo = 1.333333....  for as long as the type can hold. You get the idea

By doing a type cast on one of the integers, I can convert the entire result to a double before assigning it to the new variable.

Pointers

Pointers do not represent values. They represent a location in memory. To look at it simply, variables store values, but pointers store a location that points to other values.

Short C snippet that uses pointers.

In this example, I will used pointers to "return" the 2 values that I have found.

void means no return type of the function.

*max1 and *max2 are pointers. The function calling findLargest2 will give it references such as:

findLargest2([4, 6, 7, 69], 4m &big1, &big2); // calling the findLargest2 function

&big1 and &big2 are references. When *max1 is changed, C will look at the location that *max1 is pointing to and assign the new value into that location.

To summarise

In this part, I only talked about types, type casting and pointers. Stay tune as I learn to write more C and write more on this blog.


Additional Reading Materials

C Program Compilation Process - Jennifer Huang on Medium
https://medium.com/@earthtojhuang/gcc-main-c-9f6ee2e6894b

How the Compilation Process Works for C Programs - Wendy Leung on Medium
https://medium.com/datadriveninvestor/compilation-process-db17c3b58e62