PPL QB Answers
PPL QB Answers
1. List the different classes of binding times. Explain with suitable example.
Answer:
Binding time refers to the point in the development or execution process when attributes of
program entities—such as variables, functions, or objects—are fixed or “bound” to their
corresponding values, types, or memory locations. The main classes of binding times are:
- Definition: This is when properties of language constructs are decided by the language
designer.
- Example: Deciding that in a language, an integer variable is fixed to a specific size (e.g.,
32-bit) is a design-time decision.
2. Compile Time:
- Definition: At compile time, many bindings, such as type-checking and constant values,
are determined. The compiler resolves references, checks types, and may even perform
optimizations based on constant expressions.
- Example: In C, if you write `const int x = 5;`, the value `5` is bound to `x` at compile
time. The compiler uses this information to check the rest of the code for correctness.
3. Link Time:
- Definition: Link time binding occurs when multiple compiled modules or object files are
combined to form an executable. At this stage, unresolved symbols or references between
modules are resolved.
4. Load Time:
- Definition: Load time binding happens when the program is loaded into memory for
execution. The system loader assigns final memory addresses for the program’s code and
data.
- Example: A dynamically linked library (DLL) or shared library’s memory addresses are
resolved when the executable is loaded into memory. This allows the same library to be
used by different programs while using different memory addresses.
5. Run Time:
- Definition: Run time binding is the process when decisions are made during the actual
execution of the program. This includes actions like dynamic dispatch, memory allocation,
and binding variables to values resulting from user inputs or calculations.
Answer:
• Imperative Programming
• Declarative Programming
• Functional Programming
• Object-Oriented Programming
• Logic Programming
• Aspect-Oriented Programming
• Concurrent/Parallel Programming
1. Imperative Programming:
Description:
Imperative programming centers around describing how a program should achieve its
outcome through a sequence of statements that change program state. This paradigm uses
commands like loops, conditional statements, and variable assignments to produce a
result. The programmer lays out exact steps for the computer to follow.
#include <stdio.h>
int main() {
int sum = 0;
sum += i;
return 0;
}
• In this code, the loop iterates over the numbers, and the variable sum accumulates
the total. Each step is explicitly defined, which is characteristic of the imperative
approach.
2. Functional Programming:
• Description:
Functional programming is based on the concept of pure functions and avoids side
effects and mutable state. In this paradigm, computation is performed by applying and
composing functions, and results depend solely on the input parameters. This leads to
clearer, more predictable code as each function is like a mathematical function.
• Example:
Below is a simple example in Script that uses a functional programming approach to
calculate the sum of an array of numbers:
• In this example, the reduce function is used to combine the list of numbers into a
single sum, without any explicit state changes or iterative loops. The code
emphasizes the use of pure functions and immutability, key characteristics of
functional programming.
3. List attributes of a good programming language and explain any two in detail.
Answer:
A good programming language should have a simple syntax that is easy to learn and
understand. This reduces the effort needed to write, read, and maintain code. Readability
helps programmers quickly understand the codebase, which is especially important in
collaborative environments. For instance, languages like Python emphasize clean
indentation and straightforward syntax, making it easier to catch mistakes and debug the
program. Simple language design also minimizes the likelihood of errors, thereby
increasing the overall reliability of the software.
• Portability:
Portability refers to the ability of code written in a programming language to run on different
platforms and operating systems with little or no modification. A portable language
abstracts away underlying hardware or OS-specific details, enabling developers to write
code that is reusable in various environments. For example, languages that compile to
intermediate bytecode (like ) or that are interpreted (like Python) can run on multiple
operating systems without changes to the source code. This attribute is crucial for
developing cross-platform applications, reducing development and maintenance costs,
and ensuring broader usability of the software.
3. What are the different ways by which computer might be constructed? Explain
with example of web application.
Answer:
One way to interpret the question is by considering the various construction paradigms for
computers or computing systems. In general, computers can be constructed in the
following ways:
Hardware Construction
Traditional computers are built from physical components (CPUs, memory, input/output
devices) assembled on a circuit board. The design can follow various architectures such
as:
Von Neumann Architecture: Uses a single memory space for both instructions and data.
Harvard Architecture: Separates memory for instructions and data, allowing simultaneous
access.
A web application running on a physical server uses processors, RAM, and storage built
with these hardware principles. For instance, a server hosting a website might use a multi-
core CPU and large RAM to handle many simultaneous users.
Distributed Architecture: Splits tasks among multiple computers to improve scalability and
reliability.
Cloud Computing: Utilizes virtualized resources spread over many physical machines in
data centers.
Instead of direct hardware interaction, many modern systems use virtual machines or
containers where software creates an "artificial" computer environment on top of physical
hardware.
Containers: Package code and dependencies together, running isolated from other
processes.
Many web applications are deployed using containers (like Docker) managed in an
orchestration system (like Kubernetes). This approach allows developers to build, test, and
deploy applications in environments that mimic real hardware but are abstracted,
scalable, and consistent across different platforms.
4. What are different parameters passing methods in programming languages with
example.
Answer: In programming languages, parameter passing methods refer to the ways in which
arguments are passed from a calling function to a called function. There are several
parameter passing methods, including:
• Pass by Value: In this method, a copy of the original value is passed to the called
function. Any changes made to the parameter within the called function do not affect
the original value in the calling function.
Example: In C, when we pass an integer variable to a function, its value is copied and
passed to the function. If the function modifies the value, it does not affect the original
variable.
• Pass by Reference: In this method, a reference to the original value is passed to the
called function. Any changes made to the parameter within the called function affect
the original value in the calling function.
Example: In C++, when we pass an integer variable to a function using a pointer or a
reference, any changes made to the parameter within the function affect the original
variable.
• Pass by Name: In this method, the actual parameter is not evaluated until it is used
within the called function. This method is not commonly used in modern programming
languages.
Example: In Algol, a programming language developed in the 1950s, pass by name was
used. When a parameter was passed to a function, its value was not evaluated until it
was used within the function.
• Pass by Constant: In this method, a copy of the original value is passed to the called
function, but the called function is not allowed to modify the value.
Example: In C++, when we pass a variable to a function using the const keyword, the
function is not allowed to modify the value.
• Pass by Result: In this method, the called function returns a value to the calling
function, which is then assigned to the original variable.
Example: In functional programming languages, such as Haskell, pass by result is used.
The called function returns a value, which is then assigned to the original variable.
• Pass by Value-Result: In this method, a copy of the original value is passed to the called
function, and the called function returns a value to the calling function, which is then
assigned to the original variable.
Example: In Ada, a programming language developed in the 1980s, pass by value-result
is used. The called function receives a copy of the original value and returns a value,
which is then assigned to the original variable.
5. What are the different primitive data types? Explain with the examples of
syntax, size and ranges.
Answer:
Primitive data types are the basic building blocks for data manipulation in many
programming languages. They are not objects, and they store simple values. The following
are common primitive data types:
- int:
- Syntax (/C/C++):
- short:
- Syntax:
short s = 30000;
- long:
- Syntax:
- byte:
- Syntax:
- float:
- Syntax:
float pi = 3.14f;
- Range: Provides approximately 6-7 decimal digits of precision; accepted range is large,
but precision is limited.
- double:
- Syntax:
- Range: Provides approximately 15-16 decimal digits of precision. It allows for a much
smaller error in calculations than float.
- Syntax:
- Size: Typically 2 bytes (16 bits) in (to support Unicode); in C/C++ it is typically 1 byte.
- Range: In , it can represent characters with Unicode values from `'\u0000'` (0) to
`'\uffff'` (65,535). In the C/C++ context, the range depends on the encoding used.
- Syntax:
- Size: Not defined precisely in languages like ; it simply holds true or false values.
Answer:
Consider a class representing a number. We might want to overload the unary minus (-)
operator so that it negates the value stored in an object of that class.
#include <iostream>
class Number {
private:
int value;
public:
return Number(-value);
};
int main() {
Number n(10);
return 0;
- When we write `-n`, the overloaded unary operator is called, and it returns a new
`Number` object with the value negated.
Short circuit evaluation is a programming language feature where the evaluation of a logical
expression stops as soon as the outcome is determined. This is typically used with the
logical operators AND (`&&`) and OR (`||`). When using these operators, if the result can
be determined from the first operand, the second operand is not evaluated.
Consider the logical AND (`&&`) operator where the first operand is false. In such a case,
even if the second operand involves a function call or computation, it won’t be executed
because the entire expression will definitely be false.
#include <iostream>
bool checkSecond() {
return true;
int main() {
} else {
return 0;
- Since `condition` is false, the program does not call `checkSecond()`, because
regardless of its return value, the whole expression is false. This is short circuit evaluation
in action.
8. What are subprograms? List and explain the design issues for subprograms.
Answer:
Subprograms Overview
- Parameter Types and Number: Decide what inputs are necessary for the subprogram.
This includes the data types and the number of parameters needed.
- Return Type: Determine if the subprogram should return a value and what type it should
be.
- Readability and Intuitiveness: The names and order of parameters should be clear and
reflect their roles, making the subprogram easy for others to use.
- Side Effects: Consider how changes within the subprogram affect external variables.
Minimizing side effects can lead to more predictable and maintainable code.
- Local vs. Global Variables: Determine which variables should be local (visible only
within the subprogram) to prevent unintended interference from other parts of the program.
- Lifetime Management: Ensure that the variables declared within a subprogram are valid
only during its execution unless explicitly required otherwise (as with static variables).
- Encapsulation: Hide the internal implementation details so that the subprogram’s user
interacts only with its interface. This abstraction simplifies changes in the implementation
later.
- Input Validation: The subprogram should validate its parameters to handle unexpected
or erroneous inputs gracefully.
- Return Mechanisms for Errors: Design a strategy for error reporting, either through
special return values, exceptions, or error codes. This ensures that errors are detected and
handled appropriately by the caller.
- Proper Base Case: When using recursion, ensure that there is a clearly defined base
case to prevent infinite recursion.
i) Hardware
ii) Firmware
iii) Software
Answer:
1. Hardware
Hardware refers to the physical components of a computer system such as the CPU,
memory, input/output devices, and storage. The hardware's capabilities set the limits and
opportunities for language design.
- Data Representation: Hardware dictates how data types (e.g., integers, floating-point
numbers) are represented in memory. This affects language design decisions regarding
precision, memory management, and performance tuning.
- Example:
In C/C++, the size of data types such as int or long may vary across different hardware
architectures (32-bit vs. 64-bit systems), impacting portability and efficiency. Compiler
optimizations are often hardware-specific to leverage the processor's capabilities.
2. Firmware
Firmware is specialized software programmed into the hardware (often stored in non-
volatile memory) that provides low-level control for the device's specific hardware. It acts
as a bridge between the physical hardware and higher-level software.
- Embedded Systems: In environments where firmware controls the entire system (such
as embedded devices), programming languages are often tailored for low-level hardware
control, minimal resource consumption, and real-time responsiveness. Languages like C,
or specialized versions of C++, are common.
- Example:
3. Software
- Operating System Services: Programming languages must operate with the services
provided by the operating system, such as process management, file systems, networking,
and security. The design of these service interfaces influences how languages structure
their standard libraries and runtime systems.
- Programming Models: The architecture of software (e.g., multi-threading, distributed
systems) influences language features like concurrency primitives, exception handling, and
memory management. Language runtime systems are designed to interface efficiently with
OS services.
- Virtual Machines and Interpreters: Some high-level languages run on virtual machines
(such as the JVM for or CLR for C#) to provide portability across different hardware
architectures. This abstraction layer allows the language to overcome differences in
hardware capabilities.
- Example:
Modern languages like and Python depend on high-level operating system features and
virtual machine optimizations in order to provide cross-platform compatibility. Their design
abstracts away the underlying hardware details, while still requiring awareness of OS-level
characteristics (like memory management and process scheduling).
10. Describe ordinal types: enumeration with 'C++' example.
Answer:
Ordinal types are data types whose values have a defined order. In other words, they allow
us to compare values using relational operators like <, >, or ==. Common examples of
ordinal types include integral types (like int or char) as well as enumerated types (enums).
Enumeration in C++
In C++, we can define an enumeration type using the keyword `enum`. An enum allows us
to define a set of named integer constants. Each constant in an enum is automatically
assigned a corresponding integer value starting from 0 (unless specified otherwise).
Because these values are integer-based and ordered, they qualify as ordinal types.
Example:
#include <iostream>
enum Color {
};
int main() {
}
// Printing the integer value of myColor
cout << "The integer value of myColor is: " << myColor <<
endl;
return 0;
Explanation:
1. Definition:
The enum `Color` defines three possible values—`RED`, `GREEN`, and `BLUE`—
which are automatically assigned the values 0, 1, and 2 respectively.
2. Usage:
In the `main` function, we declare a variable `myColor` of type `Color` and assign it the
value `GREEN`.
3. Ordinal Nature:
Since each enumerated value corresponds to an integer, you can perform comparisons
(e.g., `myColor < BLUE`). This comparison is valid because the underlying integer values
provide a natural ordering (from 0 upward).
4. Output:
Running this program will print that `myColor` comes before `BLUE` and display its
underlying integer value.
11. Consider the following program code and identify the semantic elements of the
programming language along with type of binding. Describe the same
#include <stdio.h>
int main()
int x, y;
int temp;
temp = x;
x = y;
y = temp;
return 0;
}
Answer:
1. Semantic Elements:
• Preprocessor Directive:
- The line #include <stdio.h> tells the compiler to include the Standard Input/Output
library, enabling use of scanf and printf.
• Function Declaration:
- The main() function is declared as int main() and serves as the starting point of the
program.
- Two integer variables (x and y) are declared in the main block and are available
throughout the entire main function.
- A temporary variable (temp) is declared inside an inner block. Its scope is limited to
that block, meaning it is only accessible and valid within the braces where it is declared.
• Input/Output Statements:
- scanf("%d%d", &x, &y) reads two integers from the user and stores them in x and y.
- printf("%d %d\n", x, y) prints the swapped values of the variables later in the code.
• Block Structure:
- The inner block defined with curly braces { … } provides a local scope for temp,
ensuring that its binding does not interfere with any variables declared outside the block.
2. Binding Types:
- The identifiers x, y, and temp are bound to their types during compile time. The
compiler knows the type and scope of these variables when processing the code.
- x and y, declared in main, are accessible throughout main, while temp is only
accessible inside its inner block.
- Function calls to scanf and printf are also resolved at compile/link time with bindings
to the standard library.
• Run-Time Operations:
- Even though the binding of the variables is static, the actual evaluation of
expressions (e.g., swapping values using temp) happens at runtime.
12. Write short note on:
Answer:
• Definition:
• How It Works:
- The compiler performs implicit type conversion (also known as coercion) so that
the value on the right-hand side fits into the type of the left-hand side variable.
- This conversion might involve truncation (e.g., converting float 3.9 into int 3),
possible loss of precision, or other adjustments depending on the data types involved.
• Importance:
2. Unconditional Branching:
• Definition:
• How It Works:
- When the flow of execution reaches an unconditional branch statement like goto,
the program immediately transfers control to the label specified in the statement.
- There is no decision-making process; the jump occurs every time the statement is
executed.
• Importance and Caution:
Summary:
Mixed mode assignment allows conversion between different data types during
assignment, relying on implicit type coercion, while unconditional branching provides a
direct jump to another part of the code without conditions. Both concepts are fundamental
in understanding how programming languages manage data types and control flow.