Welcome to Defining Data!

Welcome to one of the most important starting blocks in your Software Systems Development journey! Think of building a software program like cooking a gourmet meal. Before you start cooking, you need to know exactly what ingredients you have, how much space they take up in your kitchen, and what containers to put them in. In programming, our ingredients are data.

Don't worry if you have never written a line of code before or find technical terms intimidating. In this chapter, we will break down how computers store, organize, and manipulate data in a simple, step-by-step way.

1. Variables and Constants: The Storage Boxes of Code

When our program runs, it needs to remember values in the computer's memory (RAM). We give these memory locations friendly names so we can find them easily.

Variables

A variable is a named memory location whose value can change during the execution of a program.
Analogy: Think of a variable like a reusable whiteboard in a classroom. You can write a score on it, erase it, and write a brand new score later.

Constants

A constant is a named memory location whose value is set once and cannot be changed while the program is running. In C#, we use the keyword const.
Analogy: Think of a constant like words carved into stone, such as the value of Pi (\(\pi \approx 3.14159\)) or the number of months in a year (\(12\)).

Example:
const double VatRate = \(0.20\);

Key Takeaway: Use variables when values must update (like a player's score) and constants for fixed values that should never accidentally change (like a tax rate).

2. Primitive Data Types in C#

Computers need to know what kind of data they are storing so they can allocate the right amount of memory. In C#, every variable must have a declared data type.

Whole Numbers (Integers)

byte: Very small positive integers from \(0\) to \(255\) (uses \(8\) bits / \(1\) byte).
short: Small integers from \(-32,768\) to \(32,767\) (uses \(16\) bits / \(2\) bytes).
int: The standard choice for whole numbers, ranging from approximately \(-2.14 \times 10^9\) to \(+2.14 \times 10^9\) (uses \(32\) bits / \(4\) bytes).
long: Massive integers for extra large calculations (uses \(64\) bits / \(8\) bytes).

Decimal Numbers (Floating Point and Fixed Point)

float: Single-precision decimal number (uses \(32\) bits). Must have an \(f\) suffix, e.g., float temp = 36.6f;
double: Double-precision decimal number (uses \(64\) bits). This is the default choice for general scientific or mathematical decimals.
decimal: High-precision \(128\)-bit number designed specifically for financial and monetary calculations to avoid rounding errors. Must have an \(m\) suffix, e.g., decimal price = 19.99m;

Text and Characters

char: Stores a single Unicode character enclosed in single quotes, e.g., char grade = 'A';
string: Stores a sequence of zero or more characters enclosed in double quotes, e.g., string studentName = "Sarah";

True / False (Boolean)

bool: Stores only one of two possible values: true or false. Perfect for flags and decision-making logic.

Did You Know? Always use decimal instead of double when dealing with money! In computer hardware, binary floating-point numbers (like double) can produce tiny rounding errors (such as \(0.1 + 0.2 = 0.30000000000000004\)), which can cause severe issues in banking systems!

3. Naming Conventions and Identifiers

An identifier is simply the name you give to a variable, constant, method, or class. To keep code readable and professional, we follow standard rules and conventions.

Rules for Identifiers in C#

• Must begin with a letter or an underscore (_).
• Cannot contain spaces or punctuation symbols.
• Cannot be a C# keyword (like int, class, or static) unless preceded by an @ symbol.
• Are case-sensitive (totalScore and TotalScore are two different variables).

Standard Casing Conventions

camelCase: The first letter is lowercase, and each subsequent word starts with an uppercase letter. Used for local variables and method parameters (e.g., studentMark, itemPrice).
PascalCase: Every word starts with a capital letter. Used for class names, method names, and properties (e.g., CalculateTotal(), StudentRecord).
UPPERCASE: Often used for constants in some conventions, or PascalCase with the const keyword (e.g., MAX_VALUE or MaxScore).

Memory Trick: Think of a camel's hump! In camelCase, the word dips low at the start and rises in the middle: myCamelVariable.

4. Type Conversion and Casting

Sometimes you need to move data from one type to another—for example, converting user input from a text box (a string) into a number (an int) so you can do math with it.

Implicit Conversion (Widening)

This happens automatically when moving data from a smaller data type to a larger compatible data type because there is no risk of losing information.
Example: An int (\(32\) bits) automatically fits inside a double (\(64\) bits).
int myInt = 50;
double myDouble = myInt; // Automatic and completely safe!

Explicit Conversion (Casting / Narrowing)

This must be done manually when moving from a larger type to a smaller type, or between incompatible types, because data might be lost.
Example: Converting a double to an int chops off the decimal portion (truncation).
double pi = 3.99;
int wholeNumber = (int)pi; // wholeNumber becomes 3, NOT 4!

Conversion Methods and Parsing

Text strings cannot be cast using simple parentheses. Instead, we use dedicated methods:

Parse(): Converts a string representation of a number into that number type. If the text is invalid (e.g., "hello"), it crashes the program with an exception.
int age = int.Parse("17");

TryParse(): A safer way to convert a string. It returns true if the conversion succeeded, or false if it failed, without crashing your program!
bool success = int.TryParse("25", out int result);

Convert Class: Provides utility methods like Convert.ToInt32() or Convert.ToDouble() that handle null values safely.

Common Mistake to Avoid: Expecting (int)5.9 to round up to \(6\). Casting from floating-point to integer always truncates (discards) the decimals completely!

5. Variable Scope and Lifetime

Where you declare a variable determines where it can be seen and how long it lives in memory.

Local Scope

A variable declared inside a method or code block (between curly braces { }) is a local variable.
Scope: Only accessible within that specific block.
Lifetime: Created when the block executes and destroyed as soon as the block finishes.

Class Scope (Fields / Member Variables)

A variable declared directly inside a class (outside of any method) is known as a field or member variable.
Scope: Accessible by all methods throughout that class.
Lifetime: Exists for as long as the object instance itself remains in memory.

Key Takeaway: Always declare variables in the smallest scope necessary. This prevents accidental changes and saves memory!

6. Enumerations (enums)

An enum (short for enumeration) is a distinct, user-defined value type that consists of a set of named constants.
Instead of using obscure numbers like \(1\) for Monday, \(2\) for Tuesday, or numbers for order statuses, enums make code clear, descriptive, and self-documenting.

Declaring and Using an Enum

enum DayOfWeek
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

DayOfWeek today = DayOfWeek.Friday;

Under the hood, C# assigns integer values starting from \(0\) by default (Monday = 0, Tuesday = 1, etc.), but using the enum names makes your code much easier to read and debug.

7. Single-Dimensional Arrays

An array is a fixed-size collection of data elements of the same data type stored in contiguous memory locations.

Key Features of Arrays

Fixed Size: Once created, the size of an array cannot be expanded or shrunk.
Zero-Indexed: The first item is always at index \(0\), the second at index \(1\), and the last item is at index \(Length - 1\).
Length Property: You can check the total number of elements using myArray.Length.

Declaring and Initializing Arrays

Method 1: Declare size first, assign later:
int[] testScores = new int[5]; // Creates space for 5 integers (indexes 0 to 4)
testScores[0] = 85;
testScores[1] = 92;

Method 2: Immediate initialization:
string[] fruitList = { "Apple", "Banana", "Orange" }; // Size is automatically 3

Accessing Elements and Common Errors

To access an item, write the array name followed by the index in square brackets: fruitList[0] gives "Apple".

Common Pitfall (IndexOutOfRangeException): If an array has a length of \(5\), the valid index positions are \(0, 1, 2, 3, 4\). Trying to access testScores[5] will crash your program because index \(5\) does not exist!

Chapter Quick Review

Variables hold data that can change; constants hold unchangeable values.
• Choose the correct type: int for whole numbers, double for general decimals, decimal for money, string for text, and bool for true/false.
Implicit casting is automatic and safe; explicit casting requires syntax like (int) and may lose precision.
• Use TryParse() when accepting user input to prevent runtime errors.
Enums improve readability by replacing magic numbers with meaningful names.
Arrays store multiple items of the same type and are always zero-indexed (\(0\) to \(n-1\)).