0% found this document useful (0 votes)
2 views21 pages

COS 132 Notes

The document provides an overview of key programming concepts in C++, including variables, constants, conversions, mathematical operators, boolean expressions, functions, and debugging techniques. It explains the differences between implicit and explicit conversions, outlines function definitions and their components, and discusses the use of makefiles for efficient compilation. Additionally, it covers debugging methods like print statements and assertions, as well as the structure and control of loops.

Uploaded by

Tkay Moshape
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views21 pages

COS 132 Notes

The document provides an overview of key programming concepts in C++, including variables, constants, conversions, mathematical operators, boolean expressions, functions, and debugging techniques. It explains the differences between implicit and explicit conversions, outlines function definitions and their components, and discusses the use of makefiles for efficient compilation. Additionally, it covers debugging methods like print statements and assertions, as well as the structure and control of loops.

Uploaded by

Tkay Moshape
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

Variables:

1. Variables:
● Variables are placeholders for data whose values can change during
program execution.
● They are defined with a specific data type (e.g., int, float) and a name,
allowing them to store different values of that type.
● Variables are useful when dealing with data that may vary, such as user
inputs, calculations, or data processing.
2. Constants:
● Constants represent fixed values that do not change during program
execution.
● Once defined, the value of a constant remains constant throughout the
program.
● Constants are typically used for values that are known and will not change,
such as mathematical constants (e.g., π) or configuration parameters.
● In C++, constants can be defined using preprocessor directives (e.g.,
#define) or the const keyword.
● They are conventionally written in all capital letters to distinguish them
from variables and indicate their immutability.

Conversions

3. Implicit Conversions:
● Definition: Implicit conversions, also known as automatic conversions,
occur when the compiler automatically converts one data type to another.
● Occurrence: These conversions happen when expressions involve
operands of different types, and the compiler deems the conversion safe
and compatible.
● Safety: Implicit conversions are performed by the compiler only when it
can ensure that no loss of data or precision occurs.
4. Explicit Conversions (Typecasts):
● Definition: Explicit conversions, also known as typecasts, are conversions
initiated by the programmer to convert a value from one data type to
another.
● Occurrence: These conversions are manually inserted into the code by the
programmer using typecast operators.
● Usage: Explicit conversions are necessary when converting between
incompatible types or enforcing specific conversions.
5. Integer Division Truncation Error:
● Cause: In C++, when performing division with two integers, the result is
also an integer, and any fractional part is truncated.
● Mitigation: To avoid this error, ensure that at least one operand of the
division operation is of a floating-point type, which will promote the result
to a floating-point value.

Mathematical Operators:

Mathematical Operators:

● Addition (+): Calculates the sum of two operands.


● Subtraction (-): Computes the difference between two operands.
● Multiplication (*): Determines the product of two operands.
● Division (/): Divides the left operand by the right operand, performing
either integer or floating-point division based on the operand types.
● Modulus (%): Finds the remainder when the left operand is divided by the
right operand.
● Increment (++) and Decrement (--): Increase or decrease the value of an
operand by 1.
● Unary Plus (+) and Unary Minus (-): Indicate the positive or negative value
of an operand.
6. Compound Assignment Operators:
● Provide a shorthand way to update the value of a variable based on its
current value and another value.
● Examples include += (addition assignment) and -= (subtraction
assignment).
7. Comparison Operators:
● Used to compare the values of two operands and determine their
relationship.
● Return a boolean value (true or false) based on the comparison result.
● Includes operators such as equal to (==), not equal to (!=), greater than (>),
less than (<), greater than or equal to (>=), and less than or equal to (<=).

Boolean

1. Boolean Expressions:
● Are expressions that result in either true or false.
● Example: 2 > 3 results in false.
● Can involve variables, constants, and logical operators.
2. True and False Representation:
● In C++, true is represented by the integer value 1, and false is represented
by the integer value 0.
● This allows seamless integration of boolean logic with arithmetic and
bitwise operations.
3. Logical Operators:
● Binary Operators:
● || (or): Returns true if at least one operand is true.
● && (and): Returns true only if both operands are true.
● Unary Operator:
● ! (not): Returns the opposite value of the expression.
4. Grouping and Brackets:
● Expressions are often grouped using brackets for clarity and to control the
order of evaluation.
5. Examples of Boolean Expressions:
● (age == 18) || (age == 19) || (age == 20)
● (age > 17) && (age < 21)
● !(dadsBankBalance > 10000.00)
● !(loanApproved)
● (age >= 18) && !(age >= 21)
● !(age <= 17) && !(age >= 21)
6. Logical Operator Truth Tables:
● Truth tables illustrate the behavior of logical operators for different
combinations of true and false operands.
7. Syntax of Logical Operators:
● ! (not): !<booleanExpression>
● && (and): <booleanExpression1> && <booleanExpression2>
● || (or): <booleanExpression1> || <booleanExpression2>
● Precedence: ! > && > ||

Functions

1. Function Return Type:


● When a function's return type is void, it indicates that the function does not
return any value.
● Here, printMessage performs an action but does not return a value.
2. Function Parameters:
● In function declarations, void can indicate that the function takes no
parameters.
3. Void Pointers:
● A void pointer (void*) is a special type of pointer that can point to any data
type.
● It is often referred to as a universal pointer because it is not associated
with any specific data type.o an int
● However, since void pointers do not have a type, you cannot dereference
them directly without casting them to another pointer type.
4. Type Absence:
● You cannot declare a variable of type void. This is because void represents
a lack of data.

In summary, the void type in C++ is used primarily for functions that do not return
values, to indicate functions with no parameters, and for creating generic pointers that
can point to any type. These applications make void a versatile tool in C++
programming, allowing for more flexible and generalized code.

1. Functions with No Return Type and No Parameter List:


a. These functions perform actions but do not return any value and do not
accept any parameters.
i. These functions perform actions but do not return any value and do

not accept any parameters.

Overview of Function Definitions

Functions with No Return Type or Parameter List (Section 4.5.1)


These functions are defined with a void return type and empty parentheses to indicate

the absence of parameters.

Functions with a Parameter List (Section 4.5.3)


These functions are defined with a void return type but include a list of parameters

within the parentheses. Each parameter is specified with its type followed by its name.

Functions with a Return Type (Section 4.5.4)


These functions specify a return type other than void. They may or may not include a

parameter list. If parameters are included, they are specified within the parentheses,

similar to the functions with a parameter list.<< std::endl;

2. Functions with No Return Type and a Parameter List:


a. These functions do not return a value but take one or more parameters to
perform their tasks

Overview of Function Definitions

Functions with No Return Type or Parameter List (Section 4.5.1)


These functions are defined with a void return type and empty parentheses to indicate
the absence of parameters.

Functions with a Parameter List (Section 4.5.3)


These functions are defined with a void return type but include a list of parameters
within the parentheses. Each parameter is specified with its type followed by its name.

Functions with a Return Type (Section 4.5.4)


These functions specify a return type other than void. They may or may not include a
parameter list. If parameters are included, they are specified within the parentheses,
similar to the functions with a parameter list.

Functions in C++ are extremely useful for modularizing code and promoting reusability.
To enhance their functionality, functions can be extended to accept parameters,
allowing external values to be passed to them. This makes functions more flexible and
capable of performing operations on different inputs.

Function Definition with Parameters


The syntax for defining a function that accepts parameters is as follows:

● <functionName>: The name of the function.


● <FormalParameterList>: A comma-separated list of parameters, where each
parameter is defined by its type and unique name.
● <FunctionBody>: The code that defines what the function does.

Function Call with Arguments


The syntax for calling a function with parameters is:

● <ActualParameterList>: A comma-separated list of values or variables that are


passed to the function.

Formal Parameters and Actual Parameters

● Formal Parameters: Defined in the function declaration, these are placeholders


for the values that the function will work with. Each formal parameter is specified
by its type and name.
● Actual Parameters: The actual values or variables passed to the function when it
is called. These are the specific inputs the function operates on.

Return Type:

Specifies the type of data the function will return to the caller.

Can be any valid C++ data type, including void if the function does not return a value.

Example: int, double, char, void, etc.

The identifier used to call the function.

Should follow C++ naming conventions and be descriptive of the function's purpose.

Parameter List:

Specifies the input that the function accepts.

Each parameter must have a type and a name.

Multiple parameters are separated by commas.


Can be empty if the function takes no parameters.

Format for the parameter list:

Function Body:

The block of code enclosed in {} that defines the function's behavior.

Contains the statements and logic that perform the function's operations.:

Used to exit the function and return control to the calling function.

Sends a value back if the function is not void.

The add function has a return type of int, a name add, and a parameter list (int a, int b).

The function body calculates the sum of a and b.

The return statement return sum; sends the result back to the caller.

Function Overloading

Function overloading allows multiple versions of a function with the same name but
different parameter lists. This is useful for performing the same task with different
types or numbers of arguments. Overloaded functions have the same name but
different signatures, which consist of the function name and its parameter types and
number. The compiler uses these signatures to distinguish between the different
versions of the overloaded functions and determine which one to call based on the
arguments provided.

For example, a function named multiply can be overloaded to handle different data
types like integers or doubles, or different numbers of arguments. Similarly, a set of
overloaded functions named printType can be created to identify and print the type of
variable passed to them, handling variables of different types appropriately.
Summary of Function Components in C++
Return Type:

● Specifies the type of data the function returns.


● Can be any valid data type or void if no value is returned.

Function Name:

● Identifier used to call the function.


● Should follow naming conventions and be descriptive of the function's purpose.

Parameter List:

● Specifies the input the function accepts.


● Includes types and names for each parameter, separated by commas.
● Can be empty if the function takes no parameters.

Function Body:

● The block of code enclosed in {} that defines what the function does.
● Contains the statements and logic for the function's operations.

Return Statement:

● Used to exit the function and optionally return a value to the caller.
● Necessary if the function has a non-void return type, to provide the value
specified by the return type.

Summary of Makefiles in C++


Makefiles Overview:

● Makefiles are used by the make program to compile and link a system with
multiple C++ source files efficiently.
● The system designer must specify the necessary details for successful
compilation and linking.

Compiling and Linking Without Make:

● Understanding the manual process of compiling and linking is crucial before


using make.

Automating with Make:

● The make program automates the compilation and linking process.


● Makefiles contain entries that provide instructions to make.

Content and Structure of Makefile Entries:

● Makefile entries specify how to compile and link the source files.
● These entries are structured to guide make in the build process.

Macros and Rules:

● Macros and rules in makefiles help create generic, adaptable entries.


● They allow for smaller, more versatile makefiles that can easily describe different
systems.

Common Errors and Challenges:

● Common novice errors in makefile creation are discussed.


● Practical challenges are introduced to deepen understanding through hands-on
experience.
The ternary operator (?:), also known as the conditional operator, is a concise way to
express simple conditional statements in C++. It takes three operands: a condition, an
expression for true, and an expression for false. The condition must be a boolean
expression, while the expressions for true and false can be any valid expressions
resulting in a value. Both expressions must be of the same type or convertible to the
same type. If the condition is true, the operator evaluates and returns the result of the
expression for true; otherwise, it returns the result of the expression for false.

In C++, the ternary operator's structure mirrors a simple if-statement and is often
referred to as a ternary-if. It can be used to perform actions or to assign/return a result
based on a condition. For instance, it can determine the greater of two numbers or call
different functions based on a condition without using if-else statements.
Debugging

1. Print Statements: This method involves strategically placing cout statements


before and after code segments where state changes or specific conditions need
to be met. For example, to check if a variable x is even, you might use cout <<
((x % 2 == 0)) << endl;. However, a downside is the need to remove or
comment out these statements before deploying the code for actual use.
2. Assertions: Assertions in C++ are used to verify whether an expression is true.
They are particularly useful for checking conditions that should always be true
unless there's a bug in the code. When an assertion fails, it terminates the
program. To use assertions, you include the cassert header file and use the
assert macro. For instance, assert((x % 2 == 0)); ensures that x is even.
Assertions can be easily enabled or disabled using the NDEBUG macro, providing a
more elegant debugging solution compared to print statements.

Additionally, assertions can be utilized to enforce pre- and post-conditions in functions.


Placing assertions at the beginning of a function helps test pre-conditions, ensuring that
the function operates on valid input. Similarly, placing assertions just before the
function terminates checks post-conditions, verifying that the function has executed
correctly. Since assertions can be disabled, they do not affect the performance of the
code in production.
Top-factorisation. Top-factorisation is similar to bottom-factorisation. In this case the
common code is the first statement(s) that is/are executed in both the true and false
blocks. Unlike with bottom-factorisation, the statements can only be factored to before
the beginning of the if-statement if the statement(s) do not influence the condition of
the if-statement. For the high-level code snippet given in the left column of the table
below, may only be removed resulting in the code given in column 2, if is not influenced
by the statement
Repetition statements(Loops)

For-

1. Initialization: This is where loop control variables are declared and initialized. It
executes only once at the beginning of the loop and is used to set up the loop's
initial conditions.
2. Condition: The condition is evaluated before each iteration of the loop. If it
evaluates to true, the loop continues executing. If it evaluates to false, the loop
stops. It's crucial for preventing infinite loops and controlling the loop's behavior.
3. Update: This part is executed at the end of each iteration and is used to update
loop control variables. Typically, this involves incrementing or decrementing a
counter, but it can also include any operation that helps progress towards the
condition becoming false and terminating the loop.

Together, these three parts allow for precise control over the iteration process, making
the for loop especially useful when the number of iterations is known beforehand.
Additionally, variables declared within the initialization part are local to the loop and
cannot be accessed outside its scope.
In a for loop, you can initialize and update multiple variables by separating them with
commas. This is useful when the loop logic requires simultaneous updates to these
variables, such as converging two indices toward the center of an array or synchronizing
multiple counters.

Here's an example of a for loop that initializes two variables, i and j. In this loop, i
increments from 1 upwards, while j decrements from 10 downwards. The loop
continues until i is less than j, effectively demonstrating a meet-in-the-middle strategy
often used in search algorithms or when pairing elements from opposite ends of a
collection.

While-
A while loop in C++ is a variable-repetition loop controlled by a condition. The loop
continues to execute the statements within its body as long as the specified condition
remains true.

Syntax:

● The while keyword is followed by a condition in parentheses.


● If the condition evaluates to true, the loop's body (a statement or a block of
statements) executes.
● After executing the body, the condition is evaluated again.
● The loop terminates when the condition evaluates to false.

Example Usage:

A common use case for a while loop is to read an undetermined number of input values
within a specified range (e.g., 0 to 100) and calculate their sum. The loop stops when an
input value outside this range is entered. This type of loop is useful for scenarios where
the number of iterations is not known in advance.

Do While-
The do-while loop in C++ is similar to the while loop but differs in that it guarantees

the loop's body will be executed at least once because the condition is evaluated at the

end of the loop.

Syntax:

● The do keyword is followed by a block of statements enclosed in curly braces.


● After the block, the while keyword is followed by a condition in parentheses.
● The loop executes the block of statements first, then checks the condition.
● If the condition evaluates to true, the loop repeats; otherwise, it terminates.

Example Usage:

A typical use case for a do-while loop is to repeatedly prompt for user input and

process it until a specific condition is met, such as entering a negative value to

terminate the loop. This ensures that the prompt and input processing occur at least

once.
Translating a For Loop into While and Do-While Loops
A for loop in C++ is designed for scenarios where the number of iterations is
predetermined. It combines initialization, condition checking, and updating within a
single line. This loop can be converted into a while loop or a do-while loop, although
these translations handle the components of the loop differently.

Using a While Loop

● Initialization: Performed before entering the while loop.


● Condition Checking: Evaluated at the start of each iteration.
● Updating: Executed at the end of the loop body.

Using a Do-While Loop

● Initialization: Performed before entering the do-while loop.


● Condition Checking: Evaluated at the end of each iteration, ensuring the loop
body executes at least once.
● Updating: Executed at the end of the loop body, before the condition is checked
again.

In both conversions, the core logic of the loop is preserved, but the placement of
initialization, condition checking, and updating varies to fit the structure of the
respective loops.

Where pre- and post-conditions are used specifically for documenting what must be true
before a function is called and what must be true after the function has completed its
execution, loop invariants are used to document the conditions under which a loop will
execute as expected. Loop invariants, can be tested using assert statements,
introduced in Study Unit 5. A loop invariant is a formal statement about the relationship
between variables that must be true before the loop starts, before each iteration of the
loop starts and directly after the loop has completed execution. Note, a loop invariant
may be false during the execution of the body of the loop. A loop invariant is used to
reason about the correctness of the loop using formal method techniques and should
not be confused with the loop condition.
Infinite Loops and Their Uses

Dangerous Infinite Loops


Infinite loops exited with a break statement can be hazardous, particularly in large
codebases where the exit condition can become obscure and difficult to manage. Such
loops can lead to unexpected outcomes when the exit statement is not immediately
visible.

Purpose of Infinite Loops


Intentional infinite loops are used in specific scenarios where standard loops with
terminating conditions are inadequate. These loops typically monitor events or
conditions that signal when to exit, such as user actions, sensor data, or network
messages.

Applications of Infinite Loops

1. Game Loops: Continuously render frames and check for player input.
2. Networking Client-Server Applications: Handle incoming requests and
connections, such as in web servers.
3. Real-Time Data Streaming: Continuously process and stream data without
predefined termination.

Coding Intentional Infinite Loops


In intentional infinite loops, the condition always evaluates to true, ensuring the loop
runs indefinitely. The program terminates only when explicitly killed by the operating
system.

Loop Invariants

Definition and Purpose


Loop invariants are formal statements about variable relationships that must hold true:

● Before the loop starts


● Before each iteration of the loop
● After the loop completes execution
They serve to:

● Document the conditions necessary for the loop to function correctly.


● Verify the loop's correctness through assertions.

Difference from Loop Conditions


Unlike loop conditions that control loop execution, loop invariants are used to reason
about the loop's behavior and correctness. They may not hold true during the execution
of the loop body but must be true at the critical points mentioned above.

Conclusion
Infinite loops, while potentially risky, are essential for certain applications where
continuous operation is required. Loop invariants, on the other hand, are crucial for
ensuring the correctness and reliability of loop operations through formal verification.

Memory Managment-
Functions in C++: Enhancing Modularity
C++ programs achieve modularity through functions, which encapsulate reusable code
blocks for specific tasks. This modularity improves code readability and maintainability.
Here's a breakdown of key function-related concepts:

Basic Function Syntax

● Return Type: Specifies the type of data the function returns.


● Function Name: Identifier used to call the function, following C++ naming
conventions.
● Parameter List: Specifies the input the function accepts, with types and names
for each parameter.
● Function Body: Contains the actual code implementing the function's behavior.
● Return Statement: Used to exit the function and optionally return a value to the
caller.

Types of Functions

1. No Return Types and Parameters: Functions that neither return a value nor
accept parameters.
2. Return Types, No Parameters: Functions that return a value but do not accept
parameters.
3. Parameters, No Return Types: Functions that accept parameters but do not
return a value.
4. Parameters and Return Types: Functions that accept parameters and return a
value.

Function Overloading
Function overloading allows multiple functions with the same name but different
parameter lists (types or numbers) to coexist. This enables varied behavior based on
the input parameters.

Default Parameters
Functions can have default parameter values, allowing them to be called with fewer
arguments than the total number of parameters.

Pass by Reference vs. Pass by Value

Pass by Value
Traditionally, parameters are passed by value, meaning copies of the arguments are
made for the function. Changes within the function do not affect the original variables.

Pass by Reference
Parameters can be passed by reference to modify the actual parameters directly within
the function. This avoids copying and allows the function to work with the original
variables.

Advantages of Pass by Reference

● Multiple Return Values: Functions can effectively return multiple values by


modifying the parameters passed by reference.
● Efficiency: Avoids the overhead of copying large data structures.

Use Case: Swapping Values


A function that swaps the values of two variables illustrates the usefulness of pass by
reference. By passing both variables by reference, the function can directly modify their
values, reflecting the changes in the calling code.

Conclusion
Using functions with appropriate parameter passing techniques in C++ allows for more
efficient and readable code. Understanding when to use pass by value and pass by
reference is crucial for writing effective functions that meet specific requirements.
Function overloading and default parameters further enhance flexibility and usability in
function design.

You might also like