DEV Community

Cover image for Intro To Learning C

Intro To Learning C

Ethan Gustafson
`${Frontend Developer}`
Updated on ・7 min read

Table of Contents:


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 itself was actually written in the 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 and uses garbage collection.

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

Interpreters, Compilers, Assemblers

A 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 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 is a computer program written in machine language, which is Binary. Machine Code is the lowest level of software.
  • Object Code has to be placed inside of Executable, Library or Object Files.

An Interpreter 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' and 'compiled language' effectively mean that the implementation of that language is an interpreter or a compiler, respectively."

For example, the Ruby Interpreter is YARV which is a 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 is a computer program that creates Object Code by mnemonics and syntax for operations and addressing modes into their equivalent numerical value.

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

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

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:

  ethan = "Ethan", skill: "Ruby")
Enter fullscreen mode Exit fullscreen mode

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?

Procedural, Object-Oriented, and Functional Programming

A 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 is a programming paradigm, derived from structured programming, based on the concept of the procedure call. 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 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 and G.R.A.S.P principles.

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

Functional Programming

"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

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

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 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 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 details how you can run C in Ruby and how you can run Ruby in C.
  • C's execution time is very fast.


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.

Discussion (0)