Ready to practice?
Sign up to access interactive coding exercises and track your progress.
Variable Assignment and Initialization
Learn the difference between assignment and initialization, and how to work with variable values safely.
Prerequisites
Assignment vs Initialization
Understanding the difference between assignment and initialization is crucial for writing safe C++ code.
Assignment
Assignment gives a value to an already-existing variable:
int x; // Variable created but uninitialized (contains garbage)
x = 5; // Assignment - gives x the value 5
Key points:
- Variable already exists in memory
- Replaces whatever value was there before
- Uses the
=operator - Happens after the variable is declared
Initialization
Initialization gives a variable its initial value when it's created:
int x{5}; // Initialization - x gets value 5 when created
// or commonly seen in other languages
int x = 5;
Key points:
- Variable gets its first value immediately upon creation
- No garbage value ever exists
- Safer than declaring then assigning
- Combined declaration and first value assignment
Why This Matters
// Risky approach - assignment after declaration
int score; // Contains garbage value!
std::cout << score; // Undefined behavior - could print anything
score = 85; // Now it's safe
// Safe approach - initialization
int score = 85; // Safe from the start
std::cout << score; // Always prints 85
Best Practice: Always initialize variables when you declare them to avoid undefined behavior.
Types of Initialization
Copy Initialization
Uses the equals sign:
int x = 5;
double pi = 3.14159;
char grade = 'A';
Direct Initialization
Uses parentheses:
int x(5);
double pi(3.14159);
char grade('A');
Uniform Initialization (C++11) - Preferred Method
Uses braces - safer and more consistent:
int x{5};
double pi{3.14159};
char grade{'A'};
This is the preferred method for modern C++ code. Use braces {} for initialization whenever possible.
Default Initialization
When you don't provide an initial value, variables get default-initialized:
int x{}; // Default initialized to 0
double price{}; // Default initialized to 0.0
char letter{}; // Default initialized to '\0' (null character)
bool flag{}; // Default initialized to false
Important difference:
int x; // Uninitialized - contains garbage value (dangerous!)
int y{}; // Default initialized to 0 (safe)
Why use default initialization:
// Instead of this:
int count = 0;
double total = 0.0;
bool isReady = false;
// You can write this:
int count{};
double total{};
bool isReady{};
Multiple Assignment
You can assign the same value to multiple variables:
int a, b, c;
a = b = c = 10; // All three variables get value 10
Multiple assignment (chaining assignments) is generally not recommended as it can make code harder to read and debug. It can also lead to unexpected behavior in more complex scenarios.
Better Practice
Initialize variables individually for clearer, more maintainable code:
// Instead of chained assignment:
int a, b, c;
a = b = c = 10;
// Write individual assignments:
int a{10};
int b{10};
int c{10};
Compound Assignment Operators
C++ provides convenient shorthand operators for common assignment patterns. These compound assignment operators combine an operation with assignment.
Basic Compound Assignment Operators
| Operator | Operation | Long Form | Short Form |
|---|---|---|---|
+= |
Addition assignment | x = x + 5; |
x += 5; |
-= |
Subtraction assignment | x = x - 3; |
x -= 3; |
*= |
Multiplication assignment | x = x * 2; |
x *= 2; |
/= |
Division assignment | x = x / 4; |
x /= 4; |
%= |
Modulus assignment | x = x % 3; |
x %= 3; |
Examples in Action
#include <iostream>
int main() {
int score{100};
// Adding points
score += 25; // Same as: score = score + 25;
std::cout << "Score after bonus: " << score << std::endl; // 125
// Losing points
score -= 10; // Same as: score = score - 10;
std::cout << "Score after penalty: " << score << std::endl; // 115
// Doubling the score
score *= 2; // Same as: score = score * 2;
std::cout << "Doubled score: " << score << std::endl; // 230
// Half the score
score /= 2; // Same as: score = score / 2;
std::cout << "Half score: " << score << std::endl; // 115
return 0;
}
Why Use Compound Assignment Operators?
1. More Concise:
// Instead of this:
counter = counter + 1;
total = total + price;
health = health - damage;
// You can write this:
counter += 1;
total += price;
health -= damage;
2. More Efficient:
// With complex expressions, compound operators avoid recalculation:
array[expensive_function()] += 5;
// vs
array[expensive_function()] = array[expensive_function()] + 5;
3. Less Error-Prone:
// Easy to make typos with long variable names:
veryLongVariableName = veryLongVariableName + value; // Risk of typo
// Compound operator reduces this risk:
veryLongVariableName += value; // Cleaner and safer
Real-World Examples
// Game programming
int playerHealth{100};
int enemyDamage{25};
int healingPotion{30};
playerHealth -= enemyDamage; // Take damage: 75
playerHealth += healingPotion; // Use potion: 105
// Financial calculations
double balance{1000.50};
double deposit{250.75};
double withdrawal{100.25};
balance += deposit; // Deposit money: 1251.25
balance -= withdrawal; // Withdraw money: 1151.00
// Counters and accumulators
int totalItems{0};
int itemsToAdd{5};
totalItems += itemsToAdd; // Add items to inventory
Common Patterns
Incrementing counters:
int count{0};
count += 1; // Add 1
// Or even simpler: count++ (we'll learn this later)
Building totals:
double total{0.0};
double price1{19.99};
double price2{25.50};
total += price1; // Add first item
total += price2; // Add second item
Applying multipliers:
int points{50};
double multiplier{1.5};
points *= multiplier; // Apply bonus multiplier
Advanced Compound Operators
// Modulus assignment (remainder)
int number{17};
number %= 5; // 17 % 5 = 2, so number becomes 2
// Useful for wrapping values
int dayOfWeek{8};
dayOfWeek %= 7; // Wraps to 1 (Monday if 0 = Sunday)
Best Practices
• Use compound operators for clarity and conciseness
• They make your intent clear (you're modifying an existing value)
• Less typing means fewer opportunities for typos
• More efficient with complex expressions
• Make sure the variable is initialized before using compound operators
• Division by zero:
x /= 0; will crash your program• Integer division truncates:
x /= 3; might not give expected results with integers
// Common mistakes to avoid:
int x; // Uninitialized!
x += 5; // Undefined behavior - adding to garbage
// Correct approach:
int x{0}; // Properly initialized
x += 5; // Safe - adds 5 to 0, result is 5
Assignment Returns a Value
Assignment operations return the assigned value:
int x, y;
x = (y = 5); // y gets 5, then x gets 5
Best Practices:
• Use uniform initialization
{} when possible• Don't chain assignments unless necessary
• Initialize with meaningful values
Common Mistakes
// Bad - uninitialized local variable
int count; // Undefined value - not guaranteed to be any specific value
count = count + 1; // Undefined behavior - result is unpredictable!
// Good - properly initialized
int count = 0; // Explicitly set to 0
count = count + 1; // count is now 1
// Also good - default initialized
int count{}; // Default initialized to 0
count = count + 1; // count is now 1
Maybe Unused Attribute
Sometimes you declare variables that you might not use in all code paths, or you're keeping them for debugging purposes. The [[maybe_unused]] attribute tells the compiler not to warn about unused variables:
#include <iostream>
int main() {
int usedVariable{42};
[[maybe_unused]] int debugVariable{100}; // Won't generate unused variable warning
std::cout << usedVariable << std::endl;
// debugVariable is declared but not used - normally this would warn
// But [[maybe_unused]] suppresses the warning
return 0;
}
When to Use [[maybe_unused]]
void processData(int value) {
[[maybe_unused]] int originalValue{value}; // Keep for debugging
// Process the value
value *= 2;
value += 10;
// In debug builds, you might want to compare with originalValue
// but in release builds, originalValue isn't used
cout << "Result: " << value << endl;
}
Common Use Cases
int main() {
// Variables used only in debug mode
[[maybe_unused]] const bool debugMode{true};
// Parameters that might not be used in all implementations
[[maybe_unused]] int reserved{0};
// Variables for future use
[[maybe_unused]] string version{"1.0.0"};
return 0;
}
Note: [[maybe_unused]] is a C++17 feature. For older compilers, you can use:
int unusedVar{42};
(void)unusedVar; // Cast to void to suppress warnings (older method)
Summary
Understanding the difference between assignment and initialization is crucial for safe C++ programming:
Assignment vs Initialization:
- Assignment: Gives a new value to an existing variable (
x = 5;) - Initialization: Gives a variable its first value when created (
int x = 5;)
Initialization Methods:
- Copy initialization:
int x = 5;(traditional) - Direct initialization:
int x(5);(alternative) - Uniform initialization:
int x{5};(modern, recommended) - Default initialization:
int x{};(initializes to default value)
Compound Assignment Operators:
- Addition assignment:
x += 5;(same asx = x + 5;) - Subtraction assignment:
x -= 3;(same asx = x - 3;) - Multiplication assignment:
x *= 2;(same asx = x * 2;) - Division assignment:
x /= 4;(same asx = x / 4;) - Modulus assignment:
x %= 3;(same asx = x % 3;)
Key Safety Rules:
- Always initialize variables when you declare them
- Use
{}for default initialization to get safe zero values - Local variables contain garbage if not initialized
- Global variables are automatically zero-initialized
Best Practice:
Use uniform initialization {} for new code - it's safer, more consistent, and prevents many common initialization errors.
Variable Assignment and Initialization - Quiz
Test your understanding of the lesson.
Practice Exercises
Variable Initialization vs Assignment
Learn the difference between initialization and assignment, and practice using compound assignment operators.
Lesson Discussion
Share your thoughts and questions