Post

🗃️ More on Variables and Data Types

🗃️ More on Variables and Data Types

Welcome back! In the previous lesson, we learned the basics of variables (int, string, double, bool), assignment, simple arithmetic, and basic input/output. Now, let’s dive deeper into C# ‘s type system and explore more ways to manipulate data.

This post covers:

  • More numeric types (float, decimal, byte, short, long) and when to choose them.
  • Defining values that don’t change (const).
  • Letting the compiler figure out types (var).
  • Shorthand operators for common calculations (+=, ++, etc.).

(Prerequisite: Ensure you understand the concepts from the “Variables and Data Types” post.)

Lesson: Expanding Your Data Toolkit

More Numeric Types: Precision and Range

In the beginner lesson, we used int for whole numbers and double for decimals. C# offers more options, allowing you to choose the best type based on the size and precision of the number you need to store.

Integer Types (Whole Numbers):

  • byte: Stores small positive whole numbers from 0 to 255. Uses only 1 byte of memory. Good for representing things like color components or small counts.
  • short: Stores whole numbers from -32,768 to 32,767. Uses 2 bytes.
  • int: The most common choice. Stores whole numbers from roughly -2.1 billion to +2.1 billion. Uses 4 bytes.
  • long: Stores very large whole numbers (up to +/- 9 quintillion!). Uses 8 bytes. Use this if int isn’t big enough.
1
2
3
4
5
6
7
8
9
byte age = 30;
short year = 2025;
int population = 1000000;
long nationalDebt = 15000000000000L; // Note the 'L' suffix for long literals

// Example: Trying to store a large number in a smaller type
// byte smallNum = 300; // Error! 300 is too large for a byte (max 255)
// int bigNum = 3000000000; // Error! 3 billion is too large for a standard int
long veryBigNum = 3000000000L; // OK! Use long for very large numbers

Floating-Point Types (Decimal Numbers):

  • float: Single-precision floating-point number. Less precise than double but uses less memory (4 bytes). Requires an F suffix on the literal value.
  • double: Double-precision floating-point number. The default choice for most decimal calculations. Uses 8 bytes.
  • decimal: High-precision decimal number. Excellent for financial calculations where rounding errors must be minimized. Uses 16 bytes and requires an M suffix on the literal value.
1
2
3
float temperature = 98.6F; // Note the 'F'
double piApproximation = 3.1415926535;
decimal accountBalance = 1234.56M; // Note the 'M'

Choosing the right type helps manage memory usage and ensures calculations are performed with appropriate precision.

Constants: Values That Never Change

Sometimes you have a value that should never be modified after it’s set, like the mathematical constant Pi or a fixed configuration setting. For this, use the const keyword.

1
2
3
4
5
const double Pi = 3.14159;
const int MaxUsers = 100;

// Pi = 3.14; // Error! Cannot assign to a constant.
// MaxUsers++; // Error! Cannot modify a constant.

Constants make your code safer (preventing accidental changes) and clearer (signaling that a value is fixed).

Type Inference with var: Let the Compiler Decide

C# has a handy feature called type inference. If you declare a variable using the var keyword and initialize it in the same statement, the compiler will automatically figure out the correct data type based on the assigned value.

1
2
3
4
5
6
7
8
9
10
var userAge = 30;         // Compiler infers this is an 'int'
var userName = "Alice";     // Compiler infers this is a 'string'
var itemPrice = 19.99;    // Compiler infers this is a 'double' (default for decimals)
var isActive = true;      // Compiler infers this is a 'bool'
var accountBalance = 100.50M; // Compiler infers 'decimal' because of the 'M'

// var score; // Error! 'var' requires you to assign a value immediately.

// Type is fixed after declaration with var
// userAge = "Thirty"; // Error! Cannot assign string to a variable inferred as int.

Using var can make code slightly shorter, especially with complex type names. However, use it when the type is obvious from the value assigned. Sometimes, explicitly stating the type (int, string, etc.) makes the code easier to read.

Shorthand Operators: Doing More with Less

C# provides convenient shorthand operators for common operations like modifying a variable’s value based on its current value.

Compound Assignment Operators:

These combine an arithmetic operation with assignment.

  • += (Add and assign): x += 5; is the same as x = x + 5;
  • -= (Subtract and assign): y -= 3; is the same as y = y - 3;
  • *= (Multiply and assign): z *= 2; is the same as z = z * 2;
  • /= (Divide and assign): w /= 4; is the same as w = w / 4;
  • %= (Modulus and assign): r %= 3; is the same as r = r % 3; (remainder)
1
2
3
4
5
int score = 10;
score += 5; // score is now 15

double price = 20.0;
price *= 0.9; // price is now 18.0 (applying a 10% discount)

Increment and Decrement Operators:

These add or subtract 1 from a variable.

  • ++ (Increment): count++; is the same as count = count + 1; or count += 1;
  • -- (Decrement): lives--; is the same as lives = lives - 1; or lives -= 1;
1
2
3
4
5
int counter = 0;
counter++; // counter is now 1

int remainingAttempts = 3;
remainingAttempts--; // remainingAttempts is now 2

(Note: ++ and -- can be placed before or after the variable (++count vs count++). This changes *when the increment/decrement happens relative to using the variable’s value in an expression, but we’ll explore that nuance in more advanced topics. For now, using them after the variable (count++) is common and clear.)*

A Note on Type Conversion Errors

In the previous lesson, we used Convert.ToInt32() and Convert.ToDouble(). What happens if the user types “hello” when asked for a number? The program crashes!

1
2
3
4
Console.Write("Enter a number: ");
string input = Console.ReadLine();
// If input is "abc", this line will cause an error!
int number = Convert.ToInt32(input);

While full error handling is a more advanced topic, it’s important to be aware that direct conversion can fail. We’ll see safer ways to handle input later.

Tutorial: Compound Interest Calculator

Let’s practice using different numeric types (decimal for money), constants, and compound assignment operators to calculate simple compound interest.

Objective: Create a program that calculates the future value of an investment after a few years using a fixed annual interest rate.

Prerequisites: A C# console project.

Step 1: Set up Program.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;

public class Program
{
    public static void Main(string[] args)
    {
        const decimal AnnualInterestRate = 0.05M; // 5% interest rate as a constant
        int years = 3; // Number of years to calculate

        Console.Write("Enter the initial investment amount: ");
        string inputAmount = Console.ReadLine();

        // Convert input to decimal
        decimal principal = Convert.ToDecimal(inputAmount); // Using decimal for currency

        Console.WriteLine($"Initial Principal: {principal:C}"); // :C formats as currency
        Console.WriteLine($"Annual Interest Rate: {AnnualInterestRate:P}"); // :P formats as percentage
        Console.WriteLine($"Calculating for {years} years...");

        // Calculation loop will go here

        Console.WriteLine($"\nFinal value after {years} years: {principal:C}");
    }
}

Explanation: We use const decimal for the rate and decimal for the money amount. We use :C and :P for currency and percentage formatting in the output.

Step 2: Calculate Interest Year by Year

We’ll simulate the interest calculation for each year. For simplicity, we’ll just repeat the calculation years times (we’ll learn proper loops soon!).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    // ... inside Main, after initial setup ...

    // Year 1
    decimal interestYear1 = principal * AnnualInterestRate;
    principal += interestYear1; // Add interest to principal using +=
    Console.WriteLine($"After Year 1: {principal:C} (Interest: {interestYear1:C})");

    // Year 2
    decimal interestYear2 = principal * AnnualInterestRate;
    principal += interestYear2;
    Console.WriteLine($"After Year 2: {principal:C} (Interest: {interestYear2:C})");

    // Year 3
    decimal interestYear3 = principal * AnnualInterestRate;
    principal += interestYear3;
    Console.WriteLine($"After Year 3: {principal:C} (Interest: {interestYear3:C})");

    Console.WriteLine($"\nFinal value after {years} years: {principal:C}");
}

Explanation: In each step, we calculate the interest earned for that year based on the *current principal, then use += to add that interest back to the principal.*

Step 3: Build and Run

  1. Save Program.cs.
  2. Build (dotnet build) and run (dotnet run).
  3. Enter an initial investment amount (e.g., 1000).

Example Output (for input 1000):

1
2
3
4
5
6
7
8
9
Enter the initial investment amount: 1000
Initial Principal: $1,000.00
Annual Interest Rate: 5.00 %
Calculating for 3 years...
After Year 1: $1,050.00 (Interest: $50.00)
After Year 2: $1,102.50 (Interest: $52.50)
After Year 3: $1,157.63 (Interest: $55.13)

Final value after 3 years: $1,157.63

Exercise: Enhanced Rectangle Calculator

Let’s enhance the Rectangle Calculator from the previous lesson.

Project Goal: Modify the Rectangle Calculator to:

  1. Use double for width and height to allow decimal inputs.
  2. Use var for declaring the area and perimeter variables.
  3. Use compound assignment or increment/decrement operators somewhere in your code (even if slightly contrived, just for practice - maybe track the number of calculations performed?).
  4. Display the area and perimeter formatted to 2 decimal places.

Requirements:

  1. Start with the code from the Beginner Rectangle Calculator mini-project.
  2. Change int variables for dimensions, area, and perimeter to double or use var where appropriate.
  3. Use Convert.ToDouble() for input conversion.
  4. Add a counter variable (e.g., int calculationsPerformed = 0;) and increment it (calculationsPerformed++ or calculationsPerformed += 1;) after calculating area and perimeter.
  5. Format the output using string interpolation and format specifiers (e.g., {area:F2} for 2 decimal places).

Hints:

  • Formatting output: Console.WriteLine($"Area: {area:F2}");
  • Incrementing: myCounter++;

Steps:

  1. Modify your RectangleCalculator project code.
  2. Save, build, and run.
  3. Test with decimal inputs (e.g., width 10.5, height 5.2).
  4. Verify the output shows 2 decimal places and that your counter works (you’ll need to print the counter value too!).

Conclusion

This lesson expanded our knowledge of C# data types, introducing more specific integer and floating-point types (byte, long, float, decimal) and the concept of constants (const). We also learned convenient shortcuts like type inference (var) and compound assignment/increment/decrement operators (+=, *=, ++, --). Understanding these helps write more efficient and appropriate code for different situations.

This post is licensed under CC BY 4.0 by the author.