1. Introduction to C
Module 1.0 • Program Development Cycle & Fundamentals
Software is a collection of programs and a program is a collection of instructions given to the computer. Development of software is a stepwise process. Before developing software, a number of processes must be completed.
The first step is to understand the user requirements. Problem analysis arises during the requirement phase of software development. Problem analysis is done for obtaining the user requirements and to determine the input and output of the program.
For solving the problem, an algorithm is implemented. An algorithm is a sequence of steps that gives a method of solving a problem. This algorithm creates the logic of the program. On the basis of this algorithm, program code is written. The sequential steps taken before writing program code are as follows:
- User requirements
- Problem analysis
- Input and Output definition
- Designing algorithm
- Program coding
This pipeline maps out the standard Process of program development.
1.1 Design Methods
Designing is the first step for obtaining a solution to a given problem. The purpose of designing is to represent the solution for the system. It is really difficult to design a large system because the complexity of the system cannot be represented easily. So various methods have been evolved for designing.
1.1.1 Top-Down Design
Every system has several hierarchies of components. The top-level component represents the whole system. The Top-Down design method starts from the top-level component and moves down to the lowest level (bottom) component. In this design method, the system is divided into some major components. Then each major component is divided into lower-level components. Similarly, other components are divided successively till the lowest level component is reached.
1.1.2 Bottom-Up Design
The Bottom-Up design method is the reverse of the Top-Down approach. It starts from the lowest-level component and climbs up to the highest-level component. It first designs the basic components, and from these basic components, the higher-level components are built.
1.1.3 Modular Approach
It is better to divide a large system into modules. In terms of programming, a module is logically a well-defined part of a program. Each module is a separate part of the program. It is easy to modify a program written with a modular approach because changes in one module don't affect other modules of the program. It is also easy to check and fix bugs in the program at a modular level.
1.2 Programming Languages
Before learning any language, it is important to know about the various types of languages and their features. It is interesting to track what the basic requirements of early programmers were and what difficulties they faced with existing options. Programming languages can be broadly classified into two categories:
- Low level languages
- High level languages
1.2.1 Low-Level Languages
The languages in this category are Machine level language and Assembly language.
1.2.1.1 Machine Level Language
Computers can understand only digital signals, which are represented in binary digits i.e., 0 and 1. So the instructions given to the computer can only be delivered via binary codes. Machine language consists entirely of instructions that are in binary 0 or 1.
Writing a program in machine level language is a difficult task because it is not easy for programmers to remember and write commands in binary code. A machine level language program is highly error-prone, and its maintenance is very difficult. Furthermore, machine language programs are not portable. Every computer architecture has its own machine instructions, so programs written for one system configuration are not valid for others.
1.2.1.2 Assembly Language
The difficulties faced in machine level language were reduced to some extent by using a modified form of machine level language called assembly language. In assembly language, instructions are given in English-like words (called mnemonics), such as MOV, ADD, SUB, etc. Therefore, it is much easier to write and understand assembly programs.
Since a computer can natively understand only machine level language, an assembly language program must be translated into machine language. The translator software used for this process is called an assembler.
Although writing programs in assembly language is a bit easier, the programmer still has to know all the low-level architectural details related to the hardware of the computer. In assembly language, data is managed explicitly in computer registers, and each CPU layout has a completely different set of registers. Hence, assembly language programs are also not portable. However, since low-level languages interface directly with hardware, their execution speed is notably faster.
1.2.2 High-Level Languages
High-level languages are designed keeping in mind the features of portability; they are machine-independent. These utilize basic, English-like syntax, so it is easy to write and understand the programs. While programming in a high-level language, the programmer is not concerned with low-level hardware paths, meaning full attention can be paid to the actual logic of the problem being solved.
For translating a high-level language program into machine language, a compiler or an interpreter is used. Every specific language ships with its own unique compiler or interpreter layout. Classic languages in this category include FORTRAN, COBOL, BASIC, Pascal, etc.
1.3 Translators
Because computers only compute operations in binary, we use translators to transition text assets down to machine-level structures. Translators are computer programs that accept a program written in a high-level or low-level language and produce an equivalent machine language program as output. The three primary types of translators used are:
- Assembler: Used for converting the code of low-level assembly language into binary machine language.
- Compiler: Used to convert high-level source code into standalone machine code blocks.
- Interpreter: Used to convert and execute high-level program blocks statement-by-statement dynamically.
The original high-level code asset is known as the source program, and the corresponding machine language infrastructure output is known as the object program.
Although both compilers and interpreters perform equivalent conceptual tasks, there is a distinct operational difference in how they work:
- A compiler parses all instructions, searches for syntax errors across the entire codebase, and lists them at the end. If the program is entirely error-free, it converts the code into an offline executable machine asset that can run independently via separate commands.
- An interpreter tracks down code execution statement-by-statement. After checking one statement, it immediately converts that specific single line into machine code and executes it. This sequential verification loop continues continuously until the final statement runs or an error block halts the system.
1.4 History of C
In earlier days, every programming language was designed for a single specific purpose. For example, FORTRAN (Formula Translator) was used for scientific and mathematical applications, while COBOL (Common Business Oriented Language) was restricted to commercial operations. The computing field lacked a multi-paradigm language that could handle general tasks smoothly.
The C language was developed in the 1970s at AT&T Bell Laboratories by Dennis Ritchie. Initially, it was designed specifically for engineering systems software inside the UNIX operating system environment. After the advent of C, the entire UNIX kernel was systematically rewritten using it. Today, almost the entire UNIX framework, alongside the tools supplied with it (including the C compiler itself), is written in C code.
The C language is derived directly from the B language, which was written by Ken Thompson. The B language itself was adapted from a language called BCPL (Basic Combined Programming Language), developed by Martin Richards at Cambridge University.
In 1982, a standardization committee was established by ANSI (American National Standards Institute). In 1989, this standard became official, introducing ANSI C. Most modern-era production compilers conform strictly to this foundational baseline.
1.5 Characteristics of C
- Middle-Level Language: It seamlessly balances the syntax simplicity of a high-level language with the raw address-manipulation control of a low-level language. This makes it ideal for writing both consumer application programs and underlying system frameworks.
- Small and Compact: C is a lean language consisting of only 32 keywords (e.g.,
if,else,for,break). Its power is augmented by modular library functions. - Structured Architecture: It relies explicitly on specific structured blocks for program selection (
if...else,switch), repetition control loops (while,for,do...while), and immediate loop exits (break). - Portability: Programs developed in C can easily migrate from one computer layout or operating system setup to another with little to no platform adjustments.
1.6 Structure of a C Program
A C program is structurally built as a collection of one or more functional units. Every function runs a scoped set of statements to perform a dedicated task. The architecture layout maps out as follows:
/* Comments Section - General Documentation Block */
#include <stdio.h> /* Preprocessor Directives */
#define PI 3.14159
int global_variable; /* Global Variable Declarations */
int main() { /* Execution Entry Point Function */
local_variables;
statements;
return 0;
}
void function_1() { /* User-Defined Functional Subroutines */
local_variables;
statements;
}
- Comments: Can be placed anywhere and are enclosed within
/*and*/delimiters. They are discarded by compilers and used for developer documentation. - Preprocessor Directives: Preprocessed before structural compilation starts. Typical examples are
#include(for header file attachments) and#define(for defining symbolic constants). - Functions: Execution always begins exactly at the entry point of the
main()function block. Variables declared within a function block are designated local to that functional scope, while global parameters remain accessible anywhere across the entire workspace.
1.7 Environment for C
The operational steps required to process and run a C asset follow a straightforward execution pipeline:
- Program Creation: Writing source code inside an editor and saving it with a
.cextension. - Program Compilation: Passing the source asset through a compiler to check syntax and output native machine code.
- Program Execution: Running the final executable object binary within the operating framework.
Click your choice for each question to view feedback immediately. Complete all questions to evaluate your metric score.