Welcome to Defining Data!
Welcome to one of the most fundamental chapters in your CCEA AS 1 Software Systems Development journey: Defining Data. Think of data as the raw ingredients in a kitchen. Before a chef can cook a delicious meal, they need to know what ingredients they have, how to store them safely, and how to measure them accurately. In programming, before your code can calculate a total, display a message, or run a complex algorithm, it must know exactly what kind of data it is working with, how to store it in memory, and how to manipulate it safely.
Don't worry if you find computer memory or data types confusing at first. We will break every concept down into bite-sized, everyday pieces!
1. Understanding Data Types
A data type tells the computer two vital things:
1. How much memory to allocate for the data.
2. What operations can validly be performed on that data.
Analogy: Imagine different sized storage containers. You wouldn't pour hot soup into an open cardboard box, and you wouldn't store a single coin in a giant shipping container. Choosing the correct data type ensures your program is efficient, reliable, and error-free.
Primitive and Core Data Types in C#
In C#, data types are broadly categorised based on the kind of value they hold:
A. Integer Types (Whole Numbers)
• int: Represents standard 32-bit whole numbers (positive, negative, or zero). Range: roughly \(-2\) billion to \(+2\) billion. Example: int score = 45;
• byte: Represents small positive whole numbers from \(0\) to \(255\) (uses only 8 bits of memory).
• long: Represents very large whole numbers (64-bit). Used when numbers exceed the \(2\) billion limit of an integer. Example: long worldPopulation = 8000000000L;
B. Floating-Point and Decimal Types (Fractional / Real Numbers)
• float: 32-bit floating-point number, offering around 7 digits of precision. Suffix with f. Example: float temperature = 21.5f;
• double: 64-bit floating-point number, offering around 15-17 digits of precision. This is the default choice in C# for decimal numbers. Example: double average = 87.65;
• decimal: 128-bit highly accurate data type, offering 28-29 digits of precision. Suffix with m. Designed specifically for financial and monetary calculations to avoid binary rounding errors! Example: decimal itemPrice = 19.99m;
C. Character and Text Types
• char: Holds a single 16-bit Unicode character enclosed in single quotes. Example: char grade = 'A';
• string: Holds a sequence of characters (text) enclosed in double quotes. Example: string studentName = "Sarah";
D. Boolean Type
• bool: Holds only one of two possible states: true or false. Perfect for flags and conditions. Example: bool isPassed = true;
Did you know? Computers store floating-point numbers (`float` and `double`) using binary fractions. This can occasionally cause tiny rounding inaccuracies (like \(0.1 + 0.2\) equaling \(0.30000000000000004\)). That is why the decimal type was created for financial software!
Key Takeaway: Choosing the Right Data Type
Always pick the type that best fits the nature of your data:
• Counting items / loop counters → int
• Scientific measurements / standard decimals → double
• Money and currency → decimal
• Single letter or symbol → char
• Sentences or words → string
• Yes/No or On/Off states → bool
2. Variables and Constants
Programs need a way to remember information while they run. We achieve this using variables and constants.
Variables
A variable is a named storage location in memory whose value can change (vary) during program execution.
To create a variable, you must declare it by specifying its type and identifier (name):
int age; // Declaration
To give it a value, you assign or initialise it:
age = 17; // Assignment
You can combine both steps into a single line:
int age = 17; // Declaration and initialisation
Constants
A constant is a named storage location whose value is set when declared and cannot be changed during runtime. We use the const keyword.
const double VatRate = 0.20;
const int MaxLives = 3;
Why use constants?
1. Readability: Meaningful names (e.g., VatRate) are clearer than random "magic numbers" (e.g., \(0.20\)) scattered throughout code.
2. Maintainability: If the VAT rate changes to \(0.22\), you only update it in one place.
3. Safety: Prevents accidental modification of sensitive baseline values.
Naming Conventions and Rules for Identifiers
An identifier is simply the name you give to a variable, constant, method, or class.
Language Rules (Must follow or compiler will give an error):
• Must begin with a letter (a-z, A-Z) or an underscore (_).
• Cannot begin with a number.
• Cannot contain spaces or special punctuation characters (such as ?, !, @, #, %).
• Cannot use reserved C# keywords (such as class, int, for, static).
• C# is case-sensitive (score, Score, and SCORE are three distinct variables).
Standard C# Conventions (Best Practices):
• camelCase: First word lowercase, following words capitalised. Used for local variables and method parameters (e.g., studentMark, totalCost).
• PascalCase: Every word begins with a capital letter. Used for class names, methods, and often constants (e.g., BankAccount, CalculateTotal(), MaxScore).
Key Takeaway
Variables store data that can change; constants store data that must stay locked. Always use clear, self-explanatory names following camelCase for local variables and PascalCase for classes and methods.
3. Variable Scope and Lifetime
Understanding where a variable lives and where it can be used is essential to avoid tricky bugs.
Scope
Scope refers to the visibility or region of the program where a variable is recognised and accessible.
• Local Scope (Block Scope): A variable declared inside a method or block of code (between curly braces { }) is only accessible within that specific block. Once the block ends, the variable goes out of scope and cannot be seen or used by other parts of the program.
• Class / Field Scope (Instance Variables): A variable declared inside a class but outside any individual method. It is accessible to all methods within that class.
Lifetime
Lifetime refers to the time period during which a variable exists in the computer's memory.
• The lifetime of a local variable begins when the block of code executes its declaration and ends as soon as the block finishes executing (its memory is then freed).
• The lifetime of an instance variable (field) lasts as long as the object it belongs to exists in memory.
Memory Aid: Think of a local variable like a temporary sticky note you write while in a meeting. When the meeting ends, you throw it away (it's gone). A class field is like a notice pinned to the office bulletin board—everyone in the room can read it as long as the office is open!
Common Mistakes to Avoid
• Using a variable outside its block: Declaring a variable inside an if block or loop and trying to print it outside that block will cause a compile error: "The name does not exist in the current context".
• Variable shadowing: Declaring a local variable with the exact same name as a class field can cause confusion over which value is being updated.
Key Takeaway
Keep the scope of your variables as narrow as possible (declare them only where they are needed). This prevents accidental changes and conserves memory.
4. Type Conversion and Type Casting
Sometimes you need to convert data from one type to another—for example, converting user input from a textbox (which is always text/string) into an integer so you can do math on it.
1. Implicit Conversion (Automatic)
Happens automatically when converting from a smaller data type to a larger / more compatible data type. There is no risk of losing data precision.
int smallNum = 100;
double bigNum = smallNum; // Automatically converted to 100.0 without errors!
2. Explicit Casting (Manual)
Required when converting from a larger type to a smaller type, or where data loss might occur. You must explicitly tell the compiler to proceed by placing the target type in parentheses: (targetType).
double price = 19.85;
int wholePrice = (int)price; // Result is 19 (the decimal part is truncated, NOT rounded!)
3. Parsing Strings
When converting text strings to numeric types, casting with (int) does not work. Instead, we use the built-in Parse method:
string input = "42";
int userAge = int.Parse(input);
double height = double.Parse("1.78");
Caution: If the string contains invalid characters (e.g., int.Parse("forty")), your program will crash with a FormatException.
4. The Convert Class
The Convert class provides helpful helper methods for conversion between common types:
• Convert.ToInt32(value) → Converts value to int.
• Convert.ToDouble(value) → Converts value to double.
• Convert.ToDecimal(value) → Converts value to decimal.
• Convert.ToBoolean(value) → Converts value to bool.
5. Converting to String: .ToString()
Every data type in C# includes the .ToString() method, allowing any value to be turned into readable text:
int score = 99;
string displayScore = score.ToString();
Key Takeaway
Use implicit conversion for safe widening, explicit casting with (type) for narrowing, Parse or Convert to turn strings into numbers, and .ToString() to turn numbers into strings.
5. Operators and Expressions
An expression is a combination of variables, constants, literals, and operators that evaluates to a single value.
1. Arithmetic Operators
Used to perform mathematical calculations:
• Addition (+): \(5 + 3 = 8\)
• Subtraction (-): \(10 - 4 = 6\)
• Multiplication (*): \(6 \times 7 = 42\) (written as 6 * 7)
• Division (/): Performs division.
• Modulus (%): Returns the remainder of integer division. Example: \(7 \pmod 3 = 1\) (written as 7 % 3). Extremely useful for checking if a number is even or odd (num % 2 == 0).
Beware of Integer Division!
When dividing two integers, C# discards the decimal fraction:
int result = 7 / 2; → Evaluates to 3, not 3.5!
To preserve the decimal, at least one operand must be a floating-point number:
double accurateResult = 7.0 / 2; → Evaluates to 3.5.
2. Relational (Comparison) Operators
Used to compare two values. They always return a bool (true or false):
• Equal to (==): Checks if two values are equal. (Notice the double equals sign!)
• Not equal to (!=): Checks if two values are different.
• Greater than (>) and Greater than or equal to (>=)
• Less than (<) and Less than or equal to (<=)
3. Logical Operators
Used to combine multiple boolean conditions:
• Logical AND (&&): Returns true only if both conditions are true.
if (age >= 17 && hasLicense == true)
• Logical OR (||): Returns true if at least one condition is true.
if (day == "Saturday" || day == "Sunday")
• Logical NOT (!): Reverses the boolean value.
if (!isFinished) (means "if NOT finished")
4. Compound Assignment and Increment/Decrement Operators
Shorthand notations to make code cleaner:
• x += 5; is equivalent to \(x = x + 5\)
• x -= 2; is equivalent to \(x = x - 2\)
• x *= 3; is equivalent to \(x = x \times 3\)
• Increment (++): x++; increases \(x\) by \(1\).
• Decrement (--): x--; decreases \(x\) by \(1\).
Operator Precedence (Order of Operations)
C# follows standard operator precedence similar to BIDMAS/BODMAS:
1. Parentheses ( )
2. Increment/Decrement (++, --), Logical NOT (!)
3. Multiplicative (*, /, %)
4. Additive (+, -)
5. Relational (<, >, <=, >=)
6. Equality (==, !=)
7. Logical AND (&&)
8. Logical OR (||)
9. Assignment (=, +=, etc.)
Top Tip: When in doubt, always use parentheses ( ) to make your intended order of execution explicit and unmistakable!
Quick Revision Checklist
• Data Types: int for integers, double for standard real numbers, decimal for currency, char for single characters, string for text, and bool for true/false.
• Variables vs. Constants: Variables can change during execution; constants (const) are immutable once defined.
• Scope: Local variables only exist inside their enclosing block { }; class fields are accessible across the entire class.
• Casting & Conversion: Implicit casting is safe/automatic; explicit casting (int) truncates decimals; text input needs int.Parse() or Convert.ToInt32().
• Integer Division: \(7 / 2\) gives \(3\); use \(7.0 / 2\) to get \(3.5\).
• Equality vs Assignment: Single equals = assigns a value; double equals == checks for equality.