Skip to content

C Variables and Constants ๐Ÿ“ฆ โ€‹

๐ŸŽฏ Overview โ€‹

Variables and constants are fundamental building blocks of C programs. Variables are used to store data that can change, while constants represent data that remains unchanged during program execution. Understanding how to use them is an essential foundation for learning C.

๐Ÿ“ What are Variables? โ€‹

Variable Concept โ€‹

Variables are named memory locations for storing data. You can think of a variable as a labeled box used to hold different types of data.

Three Elements of Variables โ€‹

  1. Variable Name: Identifier for referencing the variable
  2. Data Type: Determines what kind of data the variable can store
  3. Variable Value: The actual data stored in the variable

Variable Declaration โ€‹

c
// Basic syntax: data_type variable_name;
int age;              // Declare an integer variable
float price;          // Declare a floating-point variable
char grade;           // Declare a character variable

Variable Initialization โ€‹

c
// Initialize while declaring
int age = 25;
float price = 99.99;
char grade = 'A';

// Declare first, then assign
int count;
count = 10;

// Declare multiple variables at once
int x = 1, y = 2, z = 3;

Variable Naming Rules โ€‹

โœ… Allowed Naming Rules:

  • Composed of letters, digits, and underscores
  • Must start with a letter or underscore
  • Case-sensitive (age and Age are different variables)
c
// Legal variable names
int age;
int student_count;
int _temp;
int value123;

โŒ Not Allowed Names:

c
int 123abc;      // Cannot start with a digit
int my-var;      // Cannot contain hyphens
int int;         // Cannot use keywords
int my var;      // Cannot contain spaces

Variable Naming Suggestions โ€‹

c
// Use meaningful names
int studentAge;           // Good: Clear meaning
int sa;                   // Bad: Unclear meaning

// Use camelCase or snake_case
int studentCount;         // camelCase
int student_count;        // snake_case

// Use uppercase for constants
#define MAX_SIZE 100
const int BUFFER_SIZE = 256;

๐Ÿ”ข Variable Scope โ€‹

Local Variables โ€‹

Variables declared inside a function or code block are only valid within that scope.

c
#include <stdio.h>

void myFunction() {
    int localVar = 10;    // Local variable
    printf("Local variable: %d\n", localVar);
}

int main() {
    myFunction();
    // printf("%d", localVar);  // Error! localVar is not visible here
    return 0;
}

Global Variables โ€‹

Variables declared outside all functions can be accessed throughout the entire program.

c
#include <stdio.h>

int globalVar = 100;      // Global variable

void function1() {
    printf("Function1 accessing global variable: %d\n", globalVar);
}

void function2() {
    globalVar = 200;      // Modify global variable
    printf("Function2 modified global variable: %d\n", globalVar);
}

int main() {
    printf("Main function accessing global variable: %d\n", globalVar);
    function1();
    function2();
    printf("Modified global variable: %d\n", globalVar);
    return 0;
}

Static Variables โ€‹

Declared with the static keyword, static variables retain their values between function calls.

c
#include <stdio.h>

void counter() {
    static int count = 0;  // Static local variable, initialized only once
    count++;
    printf("Call count: %d\n", count);
}

int main() {
    counter();  // Output: Call count: 1
    counter();  // Output: Call count: 2
    counter();  // Output: Call count: 3
    return 0;
}

๐Ÿ’Ž What are Constants? โ€‹

Constants are values that cannot be changed during program execution. Using constants improves code readability and maintainability.

1๏ธโƒฃ Literal Constants โ€‹

Literals are fixed values written directly in code.

Integer Literals โ€‹

c
int decimal = 100;        // Decimal
int octal = 077;          // Octal (starts with 0)
int hex = 0x2A;           // Hexadecimal (starts with 0x)
int binary = 0b1010;      // Binary (C23 standard, some compilers support)

// Long integer literals
long bigNum = 1000000L;
long long veryBig = 9223372036854775807LL;

// Unsigned integers
unsigned int positive = 100U;
unsigned long bigPositive = 1000000UL;

Floating-point Literals โ€‹

c
float pi = 3.14f;         // Single-precision (f suffix)
double e = 2.718281828;   // Double-precision (default)
double scientific = 1.5e-3;  // Scientific notation: 1.5 ร— 10^-3

// Hexadecimal floating-point (C99)
double hexFloat = 0x1.2p3;   // 1.125 ร— 2^3 = 9.0

Character Literals โ€‹

c
char letter = 'A';        // Single character
char newline = '\n';      // Escape character
char tab = '\t';          // Tab
char backslash = '\\';    // Backslash
char quote = '\'';        // Single quote

String Literals โ€‹

c
char *greeting = "Hello, World!";
char *path = "C:\\Users\\Documents";  // Backslashes in paths need escaping
char *multiline = "This is line 1\n"
                  "This is line 2\n"
                  "This is line 3";

Common Escape Characters โ€‹

Escape CharacterMeaningExample
\nNewlineprintf("Line 1\nLine 2");
\tTabprintf("Name\tAge");
\\Backslashprintf("Path: C:\\Windows");
\'Single quotechar c = '\'';
\"Double quoteprintf("He said: \"Hello\"");
\0Null characterString terminator
\rCarriage returnReturn to line start
\bBackspaceDelete previous character

2๏ธโƒฃ Symbolic Constants (Macro Definitions) โ€‹

Constants defined using the #define preprocessor directive.

Basic Usage โ€‹

c
#include <stdio.h>

#define PI 3.1415926
#define MAX_SIZE 100
#define APP_NAME "My Application"
#define VERSION "1.0.0"

int main() {
    double radius = 5.0;
    double area = PI * radius * radius;
    
    printf("Application name: %s\n", APP_NAME);
    printf("Version: %s\n", VERSION);
    printf("Circle area: %.2f\n", area);
    printf("Maximum capacity: %d\n", MAX_SIZE);
    
    return 0;
}

Macro Characteristics โ€‹

โœ… Advantages:

  • Replaced before compilation, doesn't use memory
  • Can define any type of constant
  • Can be used for conditional compilation

โŒ Disadvantages:

  • No type checking
  • Difficult to debug (replaced during preprocessing)
  • May produce unexpected side effects

Macro Functions โ€‹

c
#include <stdio.h>

// Simple macro functions
#define SQUARE(x) ((x) * (x))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))

// Multi-line macros (using backslash for line continuation)
#define SWAP(a, b) do { \
    typeof(a) temp = (a); \
    (a) = (b); \
    (b) = temp; \
} while(0)

int main() {
    int x = 5;
    printf("Square of 5: %d\n", SQUARE(x));
    printf("Max of 5 and 10: %d\n", MAX(5, 10));
    
    // โš ๏ธ Note macro side effects
    int y = 3;
    printf("Incorrect example: %d\n", SQUARE(y++));  // Result may not be expected
    
    return 0;
}

Macro Function Pitfalls โ€‹

c
// โŒ Incorrect macro definition (missing parentheses)
#define BAD_SQUARE(x) x * x

int result1 = BAD_SQUARE(2 + 3);  // Expands to: 2 + 3 * 2 + 3 = 11 (wrong!)

// โœ… Correct macro definition (with parentheses)
#define GOOD_SQUARE(x) ((x) * (x))

int result2 = GOOD_SQUARE(2 + 3);  // Expands to: ((2 + 3) * (2 + 3)) = 25 (correct!)

3๏ธโƒฃ const Constants โ€‹

Constants declared with the const keyword have type safety.

Basic Usage โ€‹

c
#include <stdio.h>

int main() {
    const int MAX_STUDENTS = 50;
    const double PI = 3.1415926;
    const char GRADE = 'A';
    
    printf("Maximum students: %d\n", MAX_STUDENTS);
    printf("Pi: %.7f\n", PI);
    printf("Grade: %c\n", GRADE);
    
    // MAX_STUDENTS = 100;  // Error! Cannot modify const variable
    
    return 0;
}

const Pointers โ€‹

c
#include <stdio.h>

int main() {
    int value1 = 10, value2 = 20;
    
    // 1. Pointer to constant (cannot modify value through pointer)
    const int *ptr1 = &value1;
    // *ptr1 = 15;     // Error!
    ptr1 = &value2;    // OK! Can change what pointer points to
    
    // 2. Constant pointer (pointer itself is constant)
    int *const ptr2 = &value1;
    *ptr2 = 15;        // OK! Can modify value
    // ptr2 = &value2; // Error! Cannot change what pointer points to
    
    // 3. Constant pointer to constant (neither can be changed)
    const int *const ptr3 = &value1;
    // *ptr3 = 15;     // Error!
    // ptr3 = &value2; // Error!
    
    return 0;
}

const vs #define Differences โ€‹

Featureconst#define
Type checkingโœ… YesโŒ No
Scopeโœ… Follows scope rulesโŒ Global replacement
Debuggingโœ… Can be debuggedโŒ Disappears after preprocessing
MemoryUses memoryDoesn't use memory
Pointersโœ… Can take addressโŒ Cannot take address
c
#include <stdio.h>

#define MACRO_PI 3.14
const double CONST_PI = 3.14;

int main() {
    // const can have address taken
    const double *ptr = &CONST_PI;  // OK
    printf("Address of CONST_PI: %p\n", (void*)ptr);
    
    // #define cannot have address taken
    // const double *ptr2 = &MACRO_PI;  // Error!
    
    return 0;
}

4๏ธโƒฃ Enumerated Constants โ€‹

Enumerations (enum) are used to define a set of related integer constants.

Basic Usage โ€‹

c
#include <stdio.h>

// Define enumeration type
enum Weekday {
    MONDAY,      // 0
    TUESDAY,     // 1
    WEDNESDAY,   // 2
    THURSDAY,    // 3
    FRIDAY,      // 4
    SATURDAY,    // 5
    SUNDAY       // 6
};

int main() {
    enum Weekday today = WEDNESDAY;
    
    printf("Today is day: %d\n", today);
    
    if (today == WEDNESDAY) {
        printf("Today is Wednesday\n");
    }
    
    return 0;
}

Specifying Enum Values โ€‹

c
#include <stdio.h>

// Custom enum values
enum Color {
    RED = 1,
    GREEN = 2,
    BLUE = 4,
    YELLOW = 8
};

// Month enumeration
enum Month {
    JAN = 1, FEB, MAR, APR, MAY, JUN,
    JUL, AUG, SEP, OCT, NOV, DEC
};

// Status codes
enum Status {
    SUCCESS = 0,
    ERROR_FILE_NOT_FOUND = -1,
    ERROR_PERMISSION_DENIED = -2,
    ERROR_INVALID_INPUT = -3
};

int main() {
    enum Color myColor = RED;
    enum Month currentMonth = MAR;
    enum Status result = SUCCESS;
    
    printf("Color value: %d\n", myColor);
    printf("Month: %d\n", currentMonth);
    printf("Status: %d\n", result);
    
    return 0;
}

Practical Application of Enums โ€‹

c
#include <stdio.h>

enum Direction {
    NORTH,
    SOUTH,
    EAST,
    WEST
};

void move(enum Direction dir) {
    switch(dir) {
        case NORTH:
            printf("Moving north\n");
            break;
        case SOUTH:
            printf("Moving south\n");
            break;
        case EAST:
            printf("Moving east\n");
            break;
        case WEST:
            printf("Moving west\n");
            break;
    }
}

int main() {
    move(NORTH);
    move(EAST);
    return 0;
}

๐ŸŽฏ Practical Examples โ€‹

Example 1: Calculate Circle Area and Circumference โ€‹

c
#include <stdio.h>

#define PI 3.1415926

int main() {
    const char *title = "Circle Calculator";
    double radius;
    
    printf("=== %s ===\n", title);
    printf("Enter circle radius: ");
    scanf("%lf", &radius);
    
    double area = PI * radius * radius;
    double circumference = 2 * PI * radius;
    
    printf("Circle area: %.2f\n", area);
    printf("Circle circumference: %.2f\n", circumference);
    
    return 0;
}

Example 2: Temperature Conversion Program โ€‹

c
#include <stdio.h>

#define FREEZING_POINT 32.0
#define CONVERSION_FACTOR 1.8

double celsiusToFahrenheit(double celsius) {
    return celsius * CONVERSION_FACTOR + FREEZING_POINT;
}

double fahrenheitToCelsius(double fahrenheit) {
    return (fahrenheit - FREEZING_POINT) / CONVERSION_FACTOR;
}

int main() {
    const char *title = "Temperature Converter";
    double temp;
    int choice;
    
    printf("=== %s ===\n", title);
    printf("1. Celsius to Fahrenheit\n");
    printf("2. Fahrenheit to Celsius\n");
    printf("Enter choice (1 or 2): ");
    scanf("%d", &choice);
    
    printf("Enter temperature: ");
    scanf("%lf", &temp);
    
    if (choice == 1) {
        printf("%.2fยฐC = %.2fยฐF\n", temp, celsiusToFahrenheit(temp));
    } else if (choice == 2) {
        printf("%.2fยฐF = %.2fยฐC\n", temp, fahrenheitToCelsius(temp));
    } else {
        printf("Invalid choice!\n");
    }
    
    return 0;
}

Example 3: Student Grade Management โ€‹

c
#include <stdio.h>

#define MAX_STUDENTS 100
#define PASS_SCORE 60

enum Grade {
    EXCELLENT = 90,
    GOOD = 80,
    AVERAGE = 70,
    PASS = 60,
    FAIL = 0
};

const char* getGradeLevel(int score) {
    if (score >= EXCELLENT) return "Excellent";
    if (score >= GOOD) return "Good";
    if (score >= AVERAGE) return "Average";
    if (score >= PASS) return "Pass";
    return "Fail";
}

int main() {
    int studentCount;
    int scores[MAX_STUDENTS];
    int passCount = 0;
    double totalScore = 0;
    
    printf("Enter number of students (max %d): ", MAX_STUDENTS);
    scanf("%d", &studentCount);
    
    if (studentCount > MAX_STUDENTS || studentCount <= 0) {
        printf("Invalid student count!\n");
        return 1;
    }
    
    // Input scores
    for (int i = 0; i < studentCount; i++) {
        printf("Enter score for student %d: ", i + 1);
        scanf("%d", &scores[i]);
        
        totalScore += scores[i];
        if (scores[i] >= PASS_SCORE) {
            passCount++;
        }
    }
    
    // Statistics
    double average = totalScore / studentCount;
    double passRate = (double)passCount / studentCount * 100;
    
    printf("\n=== Statistics ===\n");
    printf("Total students: %d\n", studentCount);
    printf("Average score: %.2f\n", average);
    printf("Passing students: %d\n", passCount);
    printf("Pass rate: %.2f%%\n", passRate);
    
    // Display each student's grade level
    printf("\n=== Grade Levels ===\n");
    for (int i = 0; i < studentCount; i++) {
        printf("Student %d: %d - %s\n", 
               i + 1, scores[i], getGradeLevel(scores[i]));
    }
    
    return 0;
}

๐Ÿ“š Best Practices โ€‹

1. Variable Naming Suggestions โ€‹

c
// โœ… Good naming
int studentAge;
int totalScore;
double averagePrice;

// โŒ Bad naming
int a;
int x123;
int temp;

2. Constant Usage Suggestions โ€‹

c
// โœ… Use constants instead of magic numbers
#define MAX_BUFFER_SIZE 1024
const int RETRY_COUNT = 3;

char buffer[MAX_BUFFER_SIZE];
for (int i = 0; i < RETRY_COUNT; i++) {
    // ...
}

// โŒ Direct use of numbers (magic numbers)
char buffer[1024];
for (int i = 0; i < 3; i++) {
    // ...
}

3. Choose Appropriate Constant Types โ€‹

c
// Simple numeric constants โ†’ use #define
#define BUFFER_SIZE 256

// Need type safety โ†’ use const
const double TAX_RATE = 0.08;

// Related integer constants โ†’ use enum
enum Status { SUCCESS, FAILURE, PENDING };

4. Initialize Variables โ€‹

c
// โœ… Initialize when declaring
int count = 0;
double price = 0.0;
char *name = NULL;

// โŒ Using uninitialized variables
int count;
printf("%d", count);  // Undefined behavior!

๐Ÿ’ก Common Errors โ€‹

Error 1: Modifying Constants โ€‹

c
const int MAX = 100;
MAX = 200;  // Compilation error!

Error 2: Missing Parentheses in Macro Definitions โ€‹

c
#define DOUBLE(x) x + x
int result = DOUBLE(3) * 2;  // Result is 8, not 12!

// Correct version
#define DOUBLE(x) ((x) + (x))

Error 3: Confusing Variable Scope โ€‹

c
int x = 10;  // Global variable

void func() {
    int x = 20;  // Local variable, hides global variable
    printf("%d", x);  // Outputs 20
}

๐Ÿ“– Summary โ€‹

Variable Points โ€‹

  • Variables store data that can change
  • Must be declared before use
  • Follow scope rules
  • Use meaningful names

Constant Points โ€‹

  • Literals: Values written directly in code
  • #define: Preprocessor macro, no type checking
  • const: Type-safe constants, recommended
  • enum: Define sets of related integer constants

Selection Recommendations โ€‹

ScenarioRecommended Approach
Simple numeric constants#define or const
Need type safetyconst
Related integer constantsenum
Conditional compilation#define
Macro functions#define (use carefully)

Next: Learn C Operators to understand how to perform various operations on variables and constants.

Content is for learning and research only.