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:
data_type variable_name; // Declaration
You can also initialize a variable at the time of declaration:
data_type variable_name = initial_value; // Declaration with initialization
For Example:
int age; // Declaration only
age = 25; // Assignment
int score = 95; // Declaration with initialization
Variable Naming Rules
When naming variables in C, follow these rules:
- Names can contain letters, digits, and underscores
- Names must begin with a letter or underscore
- Names are case-sensitive (
age
andAge
are different variables) - Names cannot contain spaces or special characters
- Cannot use C keywords (like
int
,for
,while
, etc.)
Good variable names:
int studentCount;
float temperature_celsius;
char _initial;
Bad variable names:
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:
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:
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:
float temperature = 98.6; // Single precision
double precise_num = 3.141592; // Double precision, more accurate
Character Type
The char
type stores a single character:
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:
#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.
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 sizelong
: Typically increases sizesigned
: Can represent both positive and negative values (default for most types)unsigned
: Can only represent non-negative values
Examples:
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
const float PI = 3.14159;
Using the #
define
Preprocessor Directive
#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:
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:
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 Type | Size (bytes) | Range |
---|---|---|
char | 1 | -128 to 127 |
unsigned char | 1 | 0 to 255 |
short | 2 | -32,768 to 32,767 |
unsigned short | 2 | 0 to 65,535 |
int | 4 | -2,147,483,648 to 2,147,483,647 |
unsigned int | 4 | 0 to 4,294,967,295 |
long | 4 or 8 | -2,147,483,648 to 2,147,483,647 (or larger) |
unsigned long | 4 or 8 | 0 to 4,294,967,295 (or larger) |
float | 4 | ~1.2E-38 to ~3.4E+38 |
double | 8 | ~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:
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:
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 variablesextern
: Declares a reference to a variable defined elsewhereregister
: 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:
#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
- Write a program that declares variables of each basic data type, initializes them with values, and prints them out.
- Create a program that calculates the area and perimeter of a rectangle, using appropriate data types for the dimensions.
- Experiment with type conversion by writing a program that divides two integers and displays the result as both an integer and a float.
- Write a program that uses both global and local variables, and demonstrates their scope.
Happy coding!