Intro To Learning C
Tags: c, ruby
Published: 2020-09-23 03:58:38

**Table of Contents:**

* [Introduction](#introduction)
* [Understanding Terms](#understanding-terms)
* [Interpreters, Compilers, Assemblers](#interpreters-compilers-assemblers)
* [Programming Language Levels](#programming-language-levels)
* [Procedural, Object-Oriented, and Functional Programming](#procedural-objectoriented-and-functional-programming)
* [What is a Scripting Language?](#what-is-a-scripting-language)
* [Dynamic Typing](#dynamic-typing)
* [Garbage Collection](#garbage-collection)
* [What is C?](#what-is-c)
* [Why learn the C programming language?](#why-learn-the-c-programming-language)
* [Conclusion & Next Steps](#conclusion)

# **Introduction:**

The first programming languages I messed around with were **C++** and **Python** back in early 2018. Back then I was slowly weighing my options as to how I would begin learning to code, so I never fully learned these two languages.

Fast forward to October 2019 and I'm enrolled in the online Flatiron School Software Engineering program. I was taught **Procedural** and **Object-Oriented Programming** with **Ruby** in the first month. I believe it was a really great way to start learning how to program.

I will talk a decent amount about both **Ruby** and **C**. Although I know programming fundamentals, procedural, OOP & functional programming principles, I don't really know how Ruby works behind the scenes. I don't believe that ultimately makes me a great software engineer.

So how can I learn more about computer science, computer architecture, program execution, and how high-level programming languages work behind the scenes as well as practice more data structure and algorithm challenges?

Learning C offers the great opportunity of learning everything above all at once. But before we can learn how to use the C language, we have to confirm what we know and what we should know moving forward about programming and computer science.

In my previous blogs, I would only begin to write my drafts after I finished learning and programming. This time, I will be writing out the step-by-step process I am taking to **learn C in real-time.**

I am going to be ***direct*** with terms, concepts, and code as you read onward and will reference where the information comes from. 

## **Understanding Terms**

[**Ruby**](https://en.wikipedia.org/wiki/Ruby_(programming_language)) itself was actually written in the [**C programming language**](https://en.wikipedia.org/wiki/C_(programming_language)) by Yukihiro "Matz" Matsumoto in the 1990s. It is an **interpreted high-level general-purpose scripting programming** language. It is also [**dynamically typed**](https://en.wikipedia.org/wiki/Dynamic_programming_language) and uses [**garbage collection**](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)). 

Did that sound like a lot? **What do those terms _really_ mean?**

### **Interpreters, Compilers, Assemblers**

A [**Compiler**](https://en.wikipedia.org/wiki/Compiler) is a computer program that translates code written in a programming language *into another* programming language. There are many different types of compilers. 

- The compiler for **C** will be translating **C** source code *into* ***object code***.
- [**Object code**](https://en.wikipedia.org/wiki/Object_code) is the code produced by a compiler and is **unrelated** to Object-Oriented Programming. This doesn't really describe what object code is, though. It is a portion of **machine code** that has ***not yet*** been linked into a complete program.
- [**Machine Code**](https://simple.wikipedia.org/wiki/Machine_code) is a computer program written in machine language, which is [**Binary**](https://en.wikipedia.org/wiki/Binary_code). Machine Code is the lowest level of software.
- Object Code has to be placed inside of [Executable](https://en.wikipedia.org/wiki/Executable), [Library](https://en.wikipedia.org/wiki/Library_(computing)) or [Object Files](https://en.wikipedia.org/wiki/Object_file).

---

An [**Interpreter**](https://en.wikipedia.org/wiki/Interpreter_(computing)) is a computer program that _directly_ executes instructions from a programming or scripting language ***without*** having them previously compiled into a machine language program first. There are a number of strategies the interpreter utilizes in order to do this.

> "The terms '[**interpreted language**](https://en.wikipedia.org/wiki/Interpreted_language)' and '[**compiled language**](https://en.wikipedia.org/wiki/Compiled_language)' effectively mean that the implementation of that language is an interpreter or a compiler, respectively."

For example, the **Ruby Interpreter** is [**YARV**](https://en.wikipedia.org/wiki/YARV) which is a *[bytecode](https://en.wikipedia.org/wiki/Bytecode) interpreter* that was created to greatly reduce Ruby program execution times.

Before YARV, the Ruby interpreter was **MRI**. The MRI interpreter was written in C.

---

An [**Assembler**](https://en.wikipedia.org/wiki/Assembly_language#Assembler) is a computer program that creates Object Code by [**mnemonics**](https://en.wikipedia.org/wiki/Mnemonic) and **syntax** for *operations and addressing modes* **into** their ***equivalent numerical value.***

[**Unix**](https://en.wikipedia.org/wiki/Unix) is also written in **C** along with **Assembly**.

### **Programming Language Levels**

What's all this about language levels? There are ***two kinds***:

1.) [**Low-level**](https://en.wikipedia.org/wiki/Low-level_programming_language)

Wikipedia says:

> "A **low-level** programming language is a programming language that provides little or no abstraction from a computer's instruction set architecture—commands or functions in the language map closely to processor instructions. Generally, this refers to either **machine code** or **assembly language**."

What this means is that you really are writing everything from scratch. Usually, **low-level** languages are used to write software ***directly*** for specific hardware, so they aren't portable. This means you **cannot** use the same software in different environments. For example, **Unics**(Unix) was first written in Assembly. It would only function on the type of hardware it was designed for. Unix wasn't portable until it was rewritten in **C**.

Low-level languages do not require a compiler or interpreter. They can convert to machine code themselves.

2.) [**High-level**](https://en.wikipedia.org/wiki/High-level_programming_language)

High-level programming languages are designed so that you can focus on the problem at hand without worrying about lower-level processes. They make the code look as human-readable as possible while abstracting away work you would have to do with machine language.

Let's say I created a custom `Person` class that initializes objects with two attributes: `name` and `skill`. This is how you can create an 'instance of' a `Class` in **Ruby**, using the `new` method:

```ruby
  ethan = Person.new(name: "Ethan", skill: "Ruby")
```

This will create a new object containing my data. This is very easy to understand. I told it what to do using the Ruby syntax and it did it. 

But how was that object stored into memory? Where was it stored? What enabled it to be converted into a language the computer could read? Where was it sent in order to be executed? What happens to this data when a program is done using it?

- [Categories of Programming Languages](https://cs.lmu.edu/~ray/notes/pltypes/) 

### **Procedural, Object-Oriented, and Functional Programming**

A [**Programming Paradigm**](https://en.wikipedia.org/wiki/Programming_paradigm) is a way to classify languages based on their features. A programming language can have many paradigms.

Wikipedia's description says:

> "[**Procedural Programming**](https://en.wikipedia.org/wiki/Procedural_programming) is a programming paradigm, derived from [**structured programming**](https://en.wikipedia.org/wiki/Structured_programming), based on the concept of the [**procedure call**](https://en.wikipedia.org/wiki/Subroutine). Procedures (a type of routine or subroutine) simply contain a series of computational steps to be carried out. Any given procedure might be called at any point during a program's execution, including by other procedures or itself."

Basically, procedural programming involves executing a series of steps in order to complete a task.

[**Object-Oriented Programming**](https://en.wikipedia.org/wiki/Object-oriented_programming) is a programming paradigm based on the concept of **objects**. An object can have an **identity**, **attributes**, and **behaviors**. OOP Principles involve [**S.O.L.I.D**](https://en.wikipedia.org/wiki/SOLID) and [**G.R.A.S.P**](https://en.wikipedia.org/wiki/GRASP_(object-oriented_design)) principles.

Ruby is an **object-oriented**, **procedural** and **functional** programming language.

**Functional Programming**

> "[**Functional Programming**](https://en.wikipedia.org/wiki/Functional_programming) is a programming paradigm where programs are constructed by applying and composing functions. It is a declarative programming paradigm in which function definitions are trees of expressions that each return a value, rather than a sequence of imperative statements that change the state of the program."

A lot of functional programming is taught in JavaScript.

### [**Dynamic Typing**](https://en.wikipedia.org/wiki/Dynamic_programming_language)

Ruby is dynamically typed. "A dynamically typed language is a class of high-level programming languages, which at runtime execute common programming behaviors that static programming languages perform during compilation."

### [**Garbage Collection**](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science))

Garbage collection is about memory management. The collector will remove memory from objects that are no longer used by a program. You don't have to manually garbage collect in Ruby. That is done for you behind the scenes.

### **What is a Scripting Language?**

> A [scripting](https://en.wikipedia.org/wiki/Scripting_language) or script language is a programming language for a special run-time environment that automates the execution of tasks;[1] the tasks could alternatively be executed one-by-one by a human operator. Scripting languages are often interpreted, rather than compiled.

## **What is C?**

Wikipedia says:

> "C is a general-purpose, procedural computer programming language supporting structured programming, lexical variable scope, and recursion, with a static type system. By design, C provides constructs that map efficiently to typical machine instructions. It has found lasting use in applications previously coded in assembly language. Such applications include operating systems and various application software for computer architectures that range from supercomputers to PLCs and embedded systems."

**C** is a high-level [imperative](https://en.wikipedia.org/wiki/Imperative_programming) procedural programming language. 

- **Imperative programming** is a paradigm where a developer will explicitly describe the actions a program will take.

- **Declarative programming** is a paradigm where a developer will describe what a program will accomplish, rather than describing _how_ it will accomplish it.

C is high-level compared to Assembly. C is considered low-level compared to Ruby. This is why when you search the internet what level C is on, it will tell you at times that it is low-level or high-level.

## **Why learn the C programming language?**

- Most operating systems are written in C languages. This gives you a better understanding when you approach learning what your operating system can do.
- Many programming languages are written in C. Learning it will help you become a better developer in other languages.
- Since C isn't object-oriented, you can fully focus on procedural programming.
- It will help you learn computer architecture.
- You will understand how high-level languages operate and how programs execute. 
- You can run C in Ruby and you can run Ruby in C. The [**Ruby C API**](https://silverhammermba.github.io/emberb/c/) details how you can [**run C in Ruby**](https://silverhammermba.github.io/emberb/extend/) and how you can [**run Ruby in C**](https://silverhammermba.github.io/emberb/embed/).
- C's execution time is very fast.

## **Conclusion**

That was a lot! What I learned at Flatiron is starting to make more sense. Now with that out of the way I feel more than ready to dive into learning the language.

The next blog in this series will detail **how to configure your C environment with VS Code on macOS**.