OSC.002: C Variables and Fundamental Types — Declarations, Initialization, Integers, Floating Point, char, const, and sizeof

Photorealistic systems programmer studying C variable declarations and fundamental data types in a low-level computing workshop

What You Need to Know

  • Every object in C has a type, and the type tells the compiler how the stored bits should be interpreted, how much storage is required, and which operations are valid.
  • Declaring a variable and initializing it are different actions: a declaration introduces the object and its type, while initialization gives it an initial value.
  • Portable C code does not assume that int, long, or other fundamental types have one universal byte size; use sizeof and the standard limits headers when exact properties matter.

C is a statically typed language, which means the compiler needs to know what kind of data each variable represents before the program runs. If a variable is an integer, the compiler treats its bits as an integer. If it is a floating-point value, character, pointer, array, or structure, different rules apply.

This lesson builds directly on OSC.001: C Compiler and Toolchain. That lesson showed how source code becomes an executable. OSC.002 focuses on one of the first things the compiler must understand inside that source code: what data exists, what type it has, and what value it starts with.

A variable is best thought of as a named object that occupies storage. The name lets your source code refer to the object; the type tells the compiler how to interpret and operate on that storage.

Neso Academy introduces C variables, including declaration, definition, initialization, and assignment.

Declaration, Initialization, and Assignment

A basic declaration places the type first and the variable name after it:

int miners;

This introduces an object named miners whose type is int. If it is a local automatic variable and you do not initialize it before reading it, its value is indeterminate. A safer beginner habit is to initialize variables when you create them whenever a meaningful starting value is available:

int miners = 120;
double efficiency = 17.5;
char grade = 'A';

Later assignment changes the stored value without redeclaring the variable:

miners = 128;

The distinction matters because declaration, initialization, and assignment happen under different language rules even though they can appear visually similar.

A beginner C discussion asks why variables must be defined before use—the core reason is that C needs a declared object and type so the compiler can interpret later expressions correctly.

Why C Needs Types

A type does several jobs at once. It tells the compiler how much storage an object needs, how values are represented, what arithmetic or conversions are permitted, and how expressions involving that object should be compiled.

For example, the bit pattern stored for the integer value 42 is interpreted differently from a floating-point encoding. The compiler cannot safely perform operations unless it knows which interpretation applies.

First-edition cover of The C Programming Language by Brian Kernighan and Dennis Ritchie
The first edition of The C Programming Language by Brian Kernighan and Dennis Ritchie. The book helped standardize how generations of programmers learned C’s declaration and type model. Public-domain text-based cover via Wikimedia Commons.

The Basic Integer Family

C provides several related integer types rather than one universal integer size. Common forms include:

  • char
  • short or short int
  • int
  • long or long int
  • long long or long long int

Most of these also have signed and unsigned forms. signed int is normally written simply as int. An unsigned integer cannot represent negative values, so its available range is used for zero and positive values instead.

int temperature = -5;
unsigned int fan_rpm = 5400;
long long total_hashes = 9000000000LL;

Do Not Assume int Is Always Four Bytes

On many modern systems, int is four bytes, but portable C code should not depend on that assumption unless the target platform guarantees it. The C language specifies ordering and minimum capabilities for the integer families rather than one fixed byte count for every implementation.

Use sizeof to ask the implementation how much storage a type or object occupies:

#include <stdio.h>

int main(void)
{
    printf("char: %zu byte(s)\n", sizeof(char));
    printf("int: %zu byte(s)\n", sizeof(int));
    printf("long: %zu byte(s)\n", sizeof(long));
    printf("double: %zu byte(s)\n", sizeof(double));
    return 0;
}

The result of sizeof has type size_t, which is why the portable printf conversion for these examples is %zu. The GNU C manual notes that sizeof reports the size of a type or expression in bytes; for ordinary fixed-size types this is normally determined at compile time.

freeCodeCamp’s English-language C tutorial reinforces variables, primitive data types, declarations, initialization, and how those choices affect compiled programs.

char Is an Integer Type

char is often introduced as the type used for characters, but in C it is also an integer type. A character literal such as 'A' corresponds to an integer character code in the execution character set.

char letter = 'A';
printf("%c\n", letter);
printf("%d\n", letter);

The first line prints the character representation; the second prints its integer value after the usual integer promotions. Also remember that sizeof(char) is defined as exactly 1 byte. A C byte contains CHAR_BIT bits, available from <limits.h>, and the language does not require every implementation to use eight-bit bytes.

Floating-Point Types

C’s fundamental floating-point types are:

  • float
  • double
  • long double

They represent values with fractional components and a much larger dynamic range than ordinary integers, but floating-point representation is approximate. Many decimal fractions cannot be represented exactly in binary floating point.

float voltage = 12.5f;
double efficiency = 17.25;
long double measurement = 0.000001L;

The suffix matters. An unsuffixed decimal floating constant such as 17.25 has type double; 17.25f is float; 17.25L is long double.

Bro Code’s English-language C course reinforces variables, integer and floating-point types, constants, format specifiers, and the practical syntax used throughout this lesson.

Use the Standard Limits Headers

Instead of hard-coding assumptions about maximum values, use the standard headers that describe the current implementation. <limits.h> provides integer limits such as INT_MIN, INT_MAX, and CHAR_BIT. <float.h> provides floating-point properties.

#include <limits.h>
#include <stdio.h>

int main(void)
{
    printf("INT_MIN = %d\n", INT_MIN);
    printf("INT_MAX = %d\n", INT_MAX);
    printf("CHAR_BIT = %d\n", CHAR_BIT);
    return 0;
}

If your problem requires an integer width with a precise meaning, <stdint.h> provides types such as int32_t when the implementation supports that exact-width type. That is often better than assuming a plain int has a specific width.

const Means You Should Not Modify Through That Name

The const qualifier tells the compiler that an object should not be modified through that qualified access path after initialization.

const double nominal_voltage = 12.0;

This is useful for values your program should treat as fixed after they are established. It also communicates intent to the reader. const does not mean the same thing as a preprocessor macro, and later lessons will cover the deeper pointer-related rules around const qualification.

Identifier Rules

Variable names are identifiers. A beginner-friendly naming rule is to use letters, digits, and underscores, never begin with a digit, and avoid reserved keywords such as int, return, or while.

int rack_count = 8;
double inlet_temperature = 22.4;
unsigned long error_count = 0;

Choose names that describe the meaning of the value, not merely its current contents. rack_count communicates more than x, and that becomes increasingly important as programs grow.

Common Beginner Mistakes

  • Reading an uninitialized local variable: initialize before use.
  • Assuming every integer type has the same width on every machine: query or use standard limits.
  • Using float or double as if decimal arithmetic were exact: binary floating point introduces rounding.
  • Mixing signed and unsigned values casually: conversions can produce surprising results.
  • Using sizeof with %d: use %zu because sizeof produces size_t.
  • Confusing a character literal with a string: 'A' is a character constant; "A" is a string literal.
  • Choosing a type before understanding the data: select the type based on range, precision, sign, and interface requirements.

Practical Exercise

  1. Create a file named types.c.
  2. Declare one char, one signed integer, one unsigned integer, one float, and one double.
  3. Initialize every variable at declaration.
  4. Print each value with an appropriate printf conversion.
  5. Print sizeof for each object using %zu.
  6. Include <limits.h> and print INT_MIN, INT_MAX, and CHAR_BIT.
  7. Compile with gcc -Wall -Wextra -Wpedantic types.c -o types.
  8. Run the program and compare your machine’s results with your assumptions.

Knowledge Check + Answers

  1. What does a C variable’s type tell the compiler? How the object’s stored data should be represented, interpreted, and operated on.
  2. What is initialization? Giving an object its initial value when it is created.
  3. Is int guaranteed to be four bytes? No.
  4. What operator reports a type or object’s storage size? sizeof.
  5. What type does sizeof produce? size_t.
  6. What does sizeof(char) equal? Exactly 1 byte.
  7. Where do you find INT_MAX and CHAR_BIT? <limits.h>.
  8. What are C’s three common fundamental floating types? float, double, and long double.
  9. What is the difference between 'A' and "A"? The first is a character constant; the second is a string literal.
  10. Why initialize local variables before reading them? An uninitialized automatic local object can have an indeterminate value.

Primary References

Elementary Review

A variable is a named object, and its type tells C what that object means. Start by declaring the correct type, initialize the variable before reading it, avoid assuming exact byte sizes, use sizeof and the limits headers to inspect your implementation, and choose signed, unsigned, integer, or floating-point types based on the data you actually need to represent.

Editor’s Note

The final featured image for this lesson is generated specifically for OSC.002 and is not reused in the body. The body image is a separate internet-sourced historical C reference image from Wikimedia Commons. The YouTube and Reddit embeds are separated by substantive lesson content, and ordinary lesson prose uses standard responsive Gutenberg blocks only—no bordered, shaded, card-style, callout, panel, or fixed-width text boxes.

BitcoinVersus.Tech content is provided for informational and educational purposes.

Leave a Reply