C Programming Basics: Part 2 – Variables and Data Types

C Programming Basics:
Part 2 – Variables and Data Types

Welcome to the second installment of our C programming tutorial series! In the previous post, we introduced C and wrote our first program. Now, let’s dive deeper into variables and data types, the fundamental building blocks of any C program.

Understanding Variables in C

In programming, a variable is a named storage location in the computer’s memory that holds a value which can be modified during program execution. Think of variables as labeled containers that store data.

In C, each variable must have a declared type, which tells the compiler how much memory to allocate and how to interpret the stored data. (ISO C Standard)

Variable Declaration and Initialization

In C, you must declare variables before using them. Here’s the basic syntax:

C
data_type variable_name;  // Declaration

You can also initialize a variable at the time of declaration:

C
data_type variable_name = initial_value;  // Declaration with initialization

For Example:

C
int age;          // Declaration only
age = 25;         // Assignment

int score = 95;   // Declaration with initialization

Variable Naming Rules

When naming variables in C, follow these rules:

  1. Names can contain letters, digits, and underscores
  2. Names must begin with a letter or underscore
  3. Names are case-sensitive (age and Age are different variables)
  4. Names cannot contain spaces or special characters
  5. Cannot use C keywords (like int, for, while, etc.)

Good variable names:

C
int studentCount;
float temperature_celsius;
char _initial;

Bad variable names:

C
int 1stNumber;    // Cannot start with a digit
float my-score;   // Cannot contain hyphen
char for;         // Cannot use keyword

Fundamental Data Types in C

C provides several built-in data types to handle different kinds of values. Let’s explore the basic ones:

Integer Types

Integer types store whole numbers without decimal points:

C
int age = 25;             // Regular integer
short small_num = 123;    // Smaller integer type
long large_num = 1000000; // Larger integer type

Here’s a visualization of integer types and their typical sizes:

graph TD
    A[Essential Integer Data Types in C]
    B[char] -->|1 byte| C[Range: -128 to 127]
    D[short] -->|2 bytes| E[Range: -32,768 to 32,767]
    F[int] -->|4 bytes| G[Range: -2^31 to 2^31-1]
    H[long] -->|4-8 bytes| I[Range: -2^31 to 2^31-1 or larger]

    A --> B
    A --> D
    A --> F
    A --> H

  
 
    classDef size fill:#ddd,stroke:#000;
   

Unsigned Integer Types

You can also use unsigned versions of these types to store only positive values:

C
unsigned int positive_num = 50000;    // Can only be positive, but has a larger maximum value

Floating-Point Types

Floating-point types store numbers with decimal points:

C
float temperature = 98.6;       // Single precision
double precise_num = 3.141592;  // Double precision, more accurate

Character Type

The char type stores a single character:

C
char grade = 'A';
printf("%d\n", grade);          // Prints 65, the ASCII value of 'A'

Boolean Type

C didn’t originally have a built-in boolean type. Traditionally, integers are used where 0 represents false and any non-zero value represents true. However, in modern C (C99 and later), you can use the _Bool type or include the <stdbool.h> header for a more intuitive bool type:

C
#include <stdbool.h>

bool is_valid = true;           // Using bool type with <stdbool.h>

Void Type

The void type specifies an empty set of values. It’s used primarily for functions that don’t return a value or as a generic pointer type.

C
void print_message() {          // Function that doesn't return anything
    printf("Hello!\n");
}

Type Modifiers

C allows you to modify the basic types using type modifiers to adjust their size or sign:

  • short: Typically reduces size
  • long: Typically increases size
  • signed: Can represent both positive and negative values (default for most types)
  • unsigned: Can only represent non-negative values

Examples:

C
unsigned long big_positive_num = 4000000000;  // Large positive number
long double extremely_precise = 3.14159265358979323846;

Constants in C

Constants are values that cannot be modified after declaration. There are several ways to define constants in C:

Using the const Keyword

C
const float PI = 3.14159;

Using the #define Preprocessor Directive

C
#define PI 3.14159

The difference is that #define is a preprocessor directive that performs a text substitution before compilation, while const is a type-qualified variable recognized by the compiler.

Type Conversion (Type Casting)

Sometimes you need to convert data from one type to another. This can happen in two ways:

Implicit Type Conversion

Automatic conversion done by the compiler:

C
int x = 10;
float y = 3.5;
float result = x + y;    // x is implicitly converted to float

Explicit Type Conversion (Type Casting)

Manual conversion specified by the programmer:

C
int x = 10;
int y = 3;
float result = (float)x / y;    // Explicitly convert x to float

Here’s a visualization of how type conversion works:

graph TD
    A[Source Type] -->|Conversion| B[Destination Type]
    
    subgraph "Implicit Conversion"
        C[char] --> D[int]
        D --> E[long]
        E --> F[float]
        F --> G[double]
    end
    
    subgraph "Explicit Casting Examples"
        H["float result = 9.7"] --> I["int result = (int)9.7"]
        J["Value: 9.7"] --> K["Value: 9 (truncated)"]
    end

Memory Sizes and Ranges

Here’s a table showing the typical sizes and ranges of C data types:

Data TypeSize (bytes)Range
char1-128 to 127
unsigned char10 to 255
short2-32,768 to 32,767
unsigned short20 to 65,535
int4-2,147,483,648 to 2,147,483,647
unsigned int40 to 4,294,967,295
long4 or 8-2,147,483,648 to 2,147,483,647 (or larger)
unsigned long4 or 80 to 4,294,967,295 (or larger)
float4~1.2E-38 to ~3.4E+38
double8~2.3E-308 to ~1.7E+308

Note: The exact size of these types can vary across different platforms. Use the sizeof() operator to determine the exact size on your system.

Variable Scope and Storage Classes

The scope of a variable refers to the region of the program where the variable can be accessed:

Local Variables

Declared inside a function or block and are only accessible within that function or block:

C
void function() {
    int local_var = 10;  // Local variable
    // Can use local_var here
}
// Cannot use local_var here

Global Variables

Declared outside all functions and are accessible throughout the program:

C
int global_var = 20;  // Global variable

void function() {
    // Can use global_var here
}

C also provides storage class specifiers that control the lifetime and visibility of variables:

  • auto: Default for local variables (automatically allocated and deallocated)
  • static: Preserves value between function calls, or limits visibility of global variables
  • extern: Declares a reference to a variable defined elsewhere
  • register: Suggests the compiler to store the variable in a CPU register for faster access

Practical Example

Let’s put it all together with a practical example:

C
#include <stdio.h>

// Global constant using #define
#define PI 3.14159

int main() {
    // Variable declarations with different types
    int age = 25;
    float height = 5.9;
    char initial = 'J';
    double precise_value = 123.456789;
    
    // Calculate area of a circle
    const float radius = 5.0;  // Constant using const keyword
    float area = PI * radius * radius;
    
    // Type conversion example
    int int_area = (int)area;  // Explicit conversion from float to int
    
    // Print values
    printf("Age: %d years\n", age);
    printf("Height: %.2f feet\n", height);
    printf("Initial: %c\n", initial);
    printf("Precise value: %lf\n", precise_value);
    printf("Area of circle with radius %.2f: %.2f\n", radius, area);
    printf("Area as integer (truncated): %d\n", int_area);
    
    return 0;
}

This program demonstrates variable declaration, initialization, constants, and type conversion in action.

Conclusion

Understanding variables and data types is essential for C programming. They form the foundation upon which all C programs are built. By choosing the right data type for each variable, you ensure efficient memory usage and appropriate handling of values in your programs.

In the next part of our series, we’ll dive into operators and expressions in C, which will allow us to perform operations on these variables.

Practice Exercises

  1. Write a program that declares variables of each basic data type, initializes them with values, and prints them out.
  2. Create a program that calculates the area and perimeter of a rectangle, using appropriate data types for the dimensions.
  3. Experiment with type conversion by writing a program that divides two integers and displays the result as both an integer and a float.
  4. Write a program that uses both global and local variables, and demonstrates their scope.

Happy coding!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top