README
Variables and Constants in C
š Introduction
Variables are named storage locations in memory that hold data which can be modified during program execution. Constants are values that remain fixed throughout the program. Understanding how to properly declare, initialize, and use variables and constants is fundamental to C programming.
šÆ What is a Variable?
A variable is a symbolic name for a memory location where data is stored. Think of it as a labeled box that can hold a value.
Memory Representation:
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā RAM ā
āāāāāāāāāāāā¬āāāāāāāāāāā¬āāāāāāāāāāā¬āāāāāāāāāāā¬āāāāāāāāāāā¬āāāāāāā¤
ā Address ā 0x1000 ā 0x1004 ā 0x1008 ā 0x100C ā ... ā
āāāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāā¤
ā Name ā age ā salary ā grade ā ... ā ā
āāāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāā¤
ā Value ā 25 ā 50000 ā 'A' ā ... ā ā
āāāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāāāāāā¼āāāāāāā¤
ā Type ā int ā int ā char ā ... ā ā
āāāāāāāāāāāā“āāāāāāāāāāā“āāāāāāāāāāā“āāāāāāāāāāā“āāāāāāāāāāā“āāāāāāā
Properties of a Variable:
- ā¢Name (identifier) - How we refer to the variable
- ā¢Type - What kind of data it holds
- ā¢Value - The actual data stored
- ā¢Address - Location in memory
- ā¢Scope - Where the variable is accessible
- ā¢Lifetime - How long it exists in memory
š Variable Declaration
Syntax:
data_type variable_name;
Examples:
int age; // Declares an integer variable
float salary; // Declares a float variable
char grade; // Declares a character variable
double pi; // Declares a double variable
Multiple Declarations:
// Multiple variables of same type on one line
int x, y, z;
float width, height, depth;
// Each on separate line (preferred for readability)
int count;
int total;
int average;
š Variable Initialization
Initialization means giving a variable its first value.
Syntax:
data_type variable_name = initial_value;
Examples:
int age = 25; // Integer
float price = 19.99f; // Float (note 'f' suffix)
double pi = 3.14159265358979; // Double
char grade = 'A'; // Character
char name[] = "John"; // String (character array)
Declaration vs Initialization:
int x; // Declaration only (contains garbage)
x = 10; // Assignment (later initialization)
int y = 20; // Declaration with initialization (preferred)
ā ļø Warning: Uninitialized Variables
int x; // Uninitialized!
printf("%d", x); // DANGER: Prints garbage value
// Always initialize:
int x = 0; // Safe
š Variable Naming Rules
ā Valid Rules:
- ā¢Start with letter or underscore - Not a digit
- ā¢Contain letters, digits, underscores - No special characters
- ā¢Case-sensitive -
age,Age,AGEare different - ā¢No reserved keywords - Can't use
int,for,while, etc. - ā¢No length limit - But first 31-63 characters are significant
Examples:
| Valid | Invalid | Reason |
|---|---|---|
age | 2age | Starts with digit |
_count | my-var | Contains hyphen |
myVar | my var | Contains space |
student1 | int | Reserved keyword |
MAX_SIZE | #define | Contains # |
_123 | float | Reserved keyword |
Naming Conventions:
// camelCase - Common in C
int studentAge;
float accountBalance;
char firstName[50];
// snake_case - Also common in C
int student_age;
float account_balance;
char first_name[50];
// ALL_CAPS - For constants and macros
#define MAX_SIZE 100
const int BUFFER_SIZE = 256;
// Hungarian notation - Prefix with type hint
int nAge; // n for number/int
float fPrice; // f for float
char *pName; // p for pointer
char szBuffer[100]; // sz for string (zero-terminated)
š” Best Practices:
- ā¢Use meaningful names:
studentAgenotsa - ā¢Be consistent: Pick one convention and stick to it
- ā¢Avoid single letters: Except for loop counters (
i,j,k) - ā¢Don't use reserved words: Even as part of names
- ā¢Consider scope: Longer names for wider scope
š Constants
Constants are values that cannot be changed after initialization.
Types of Constants in C:
Constants in C
ā
āāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāā
ā ā ā
Literal Symbolic Defined
Constants Constants Constants
ā ā ā
42, 3.14 const int #define MAX 100
'A', "Hi" PI = 3.14
1. Literal Constants
Values written directly in code:
// Integer literals
int a = 42; // Decimal
int b = 052; // Octal
int c = 0x2A; // Hexadecimal
// Floating-point literals
float f = 3.14f;
double d = 3.14;
double e = 6.022e23; // Scientific notation
// Character literals
char ch = 'A';
char newline = '\n';
// String literals
char greeting[] = "Hello, World!";
2. const Keyword (C89+)
The const keyword creates a read-only variable:
const int MAX_STUDENTS = 100;
const float PI = 3.14159f;
const char NEWLINE = '\n';
// Attempt to modify causes compile error:
// MAX_STUDENTS = 200; // ERROR: assignment of read-only variable
const with Pointers:
// Pointer to constant data (can't change data through pointer)
const int *ptr1 = &value;
*ptr1 = 10; // ERROR: can't modify data
ptr1 = &other; // OK: can change pointer
// Constant pointer (can't change pointer itself)
int *const ptr2 = &value;
*ptr2 = 10; // OK: can modify data
ptr2 = &other; // ERROR: can't change pointer
// Constant pointer to constant data (can't change either)
const int *const ptr3 = &value;
*ptr3 = 10; // ERROR
ptr3 = &other; // ERROR
3. #define Preprocessor Directive
Creates symbolic constants (text replacement):
#define PI 3.14159
#define MAX_SIZE 100
#define GREETING "Hello"
#define SQUARE(x) ((x) * (x))
// Usage:
float area = PI * radius * radius;
int array[MAX_SIZE];
printf("%s\n", GREETING);
int sq = SQUARE(5); // Replaced with ((5) * (5))
const vs #define:
| Feature | const | #define |
|---|---|---|
| Type checking | ā Yes | ā No |
| Debugging | ā Has symbol | ā Replaced before compile |
| Memory | ā Allocates memory | ā Text replacement |
| Scope | ā Follows scope rules | ā File scope |
| Can be pointer | ā Yes | ā No |
| Preprocessor | ā No | ā Yes |
// Prefer const for type safety:
const int MAX_VALUE = 100;
// Use #define for:
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define DEBUG_MODE 1
4. enum Constants
Create named integer constants:
enum Color { RED, GREEN, BLUE }; // RED=0, GREEN=1, BLUE=2
enum Weekday {
MONDAY = 1, // Start from 1
TUESDAY, // 2
WEDNESDAY, // 3
THURSDAY, // 4
FRIDAY, // 5
SATURDAY, // 6
SUNDAY // 7
};
// Usage:
enum Color myColor = GREEN;
enum Weekday today = FRIDAY;
š Variable Scope
Scope determines where a variable can be accessed.
Types of Scope:
#include <stdio.h>
int globalVar = 100; // GLOBAL SCOPE - accessible everywhere
void function() {
int localVar = 50; // LOCAL SCOPE - only in this function
{
int blockVar = 25; // BLOCK SCOPE - only in this block
printf("%d\n", blockVar); // OK
}
// blockVar not accessible here
printf("%d\n", localVar); // OK
printf("%d\n", globalVar); // OK
}
int main() {
printf("%d\n", globalVar); // OK
// printf("%d\n", localVar); // ERROR: not in scope
for (int i = 0; i < 5; i++) { // i has block scope (C99+)
printf("%d ", i);
}
// i not accessible here
return 0;
}
Scope Hierarchy:
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Global Scope (file level) ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā Function Scope āā
ā ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā Block Scope āāā
ā ā ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā Inner Block Scope āāāā
ā ā ā ā Variables here can access all outer scopes āāāā
ā ā ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā Outer block cannot access inner block variables āāā
ā ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā Other functions cannot access local variables āā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā All code can access global variables ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Variable Shadowing:
int x = 10; // Global x
void function() {
int x = 20; // Local x shadows global x
printf("%d\n", x); // Prints 20
{
int x = 30; // Block x shadows local x
printf("%d\n", x); // Prints 30
}
printf("%d\n", x); // Prints 20 (back to local x)
}
ā° Variable Lifetime
Lifetime is how long a variable exists in memory.
Storage Classes:
| Storage Class | Keyword | Lifetime | Scope | Default Value |
|---|---|---|---|---|
| Automatic | auto (default) | Function call | Local | Garbage |
| Static | static | Program duration | Local/Global | Zero |
| Register | register | Function call | Local | Garbage |
| External | extern | Program duration | Global | Zero |
1. Automatic Variables (auto):
void function() {
int x = 10; // auto by default
auto int y = 20; // Explicit auto (rarely used)
// Created when function is called
// Destroyed when function returns
}
2. Static Variables:
void counter() {
static int count = 0; // Initialized only once
count++;
printf("Called %d times\n", count);
}
int main() {
counter(); // Called 1 times
counter(); // Called 2 times
counter(); // Called 3 times
return 0;
}
Static at file level (internal linkage):
static int moduleVar = 0; // Only accessible in this file
static void helperFunction() { } // Only callable in this file
3. Register Variables:
void function() {
register int i; // Hint: store in CPU register
for (i = 0; i < 1000000; i++) {
// Fast access (if compiler honors the hint)
}
// Note: Can't take address of register variable
// int *ptr = &i; // ERROR
}
4. External Variables (extern):
// file1.c
int sharedVar = 100; // Definition
// file2.c
extern int sharedVar; // Declaration (use the one from file1.c)
void function() {
printf("%d\n", sharedVar); // Uses sharedVar from file1.c
}
š Variable Initialization Summary
// ============================================
// INITIALIZATION METHODS
// ============================================
// Method 1: Declaration then assignment
int a;
a = 10;
// Method 2: Declaration with initialization (preferred)
int b = 20;
// Method 3: Multiple on one line (same type)
int x = 1, y = 2, z = 3;
// Method 4: Arrays
int arr1[5] = {1, 2, 3, 4, 5}; // Full initialization
int arr2[5] = {1, 2}; // Partial (rest are 0)
int arr3[] = {1, 2, 3}; // Size inferred (3)
int arr4[5] = {0}; // All zeros
// Method 5: Structures
struct Point {
int x;
int y;
};
struct Point p1 = {10, 20}; // Positional
struct Point p2 = {.x = 10, .y = 20}; // Designated (C99)
// Method 6: Compound literals (C99)
int *ptr = (int[]){1, 2, 3, 4, 5};
ā ļø Common Mistakes
1. Using Uninitialized Variables:
int x;
printf("%d", x); // Garbage value!
// Fix: Always initialize
int x = 0;
2. Scope Confusion:
if (condition) {
int x = 10;
}
printf("%d", x); // ERROR: x not in scope
// Fix: Declare outside
int x = 0;
if (condition) {
x = 10;
}
printf("%d", x); // OK
3. Modifying Constants:
const int MAX = 100;
MAX = 200; // ERROR: can't modify const
#define VALUE 50
VALUE = 60; // ERROR: #define is not a variable
4. Naming Conflicts:
int int = 5; // ERROR: 'int' is keyword
int float = 3.14; // ERROR: 'float' is keyword
ā Best Practices
- ā¢Always initialize variables at declaration
- ā¢Use meaningful names that describe the purpose
- ā¢Prefer
constover#definefor typed constants - ā¢Minimize global variables - they make code harder to maintain
- ā¢Declare variables close to first use (C99+ allows mid-block)
- ā¢Use
staticfor file-local globals to prevent external access - ā¢Comment non-obvious initializations
š Key Takeaways
- ā¢Variables store data that can change during execution
- ā¢Constants store values that cannot be modified
- ā¢Declaration creates the variable; initialization gives it a value
- ā¢Scope determines where a variable is accessible
- ā¢Lifetime determines how long a variable exists
- ā¢Use
constfor type-safe constants - ā¢Always initialize to avoid undefined behavior
āļø Next Topic
Continue to Input/Output (scanf, printf) to learn how to read and display data.