Variables and Data Types in C: Declarations, Conversions and Runnable Examples

Learn how C types control stored values, expressions and I/O. Compile a complete marks program, trace its conversions and repair common type mistakes.

KnowledgeGate Team

Exam prep & CS education

Updated 17 Sep 20266 min read

C lets one short declaration control which values an object can store, how an expression is evaluated and which input or output format is valid. One wrong type or missing cast can still print a plausible but incorrect result. The marks-summary program shows how declarations, type families, literals, sizeof, formats and conversions determine exact outputs. The Coding & Skill Development Courses catalogue groups the broader programming path.

Related reading: C data types and operators and C type conversions.

Variables in C: Name, Type, Value and Lifetime of One Object

A variable is a named object. Its type determines which values it can represent and which operations are available. In int score = 72;, int is the type, score is the identifier and 72 is the initial value. This is initialization. A later statement, score = 81;, assigns a new value without changing the declared type.

Names such as total_marks, marks2 and _index are valid. 2marks cannot start with a digit, total-marks contains an invalid hyphen, and float is a keyword. C is case-sensitive, so score and Score name different objects. Descriptive lower-case names with underscores are a useful style, not a language rule.

In const int subject_count = 7;, const qualifies the object as one the program must not modify after initialization. It is not another numeric type. The C Programming & Data Structures hub continues into arrays, pointers and structures.

Labelled breakdown of the declaration const int subject_count = 7 with the marks program's typed value boxes beside it.

C Data Type Families Without Memorising Machine-Specific Sizes

Use type families by purpose instead of memorising one machine's size table.

Purpose

C types

Whole numbers

_Bool, char, signed char, unsigned char, and signed or unsigned forms of short, int, long and long long

Fractional values

float, double, long double

No value

void

Richer types for later

Arrays, pointers, functions, structures and unions

C implementations choose supported sizes within the language rules. An int is not guaranteed to be 4 bytes, and a long is not guaranteed to be 8. sizeof(char) is always 1 C byte, while CHAR_BIT from <limits.h> tells you how many bits that byte has.

Run this probe and record the output from your own implementation:

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

int main(void) {
    printf("char bits = %d\n", CHAR_BIT);
    printf("int bytes = %zu\n", sizeof(int));
    printf("double bytes = %zu\n", sizeof(double));
    printf("INT_MAX = %d\n", INT_MAX);
    return 0;
}

sizeof produces a size_t value, so its matching printf conversion is %zu.

Literals, Type Suffixes and Correct I/O Formats

The spelling of a literal carries type information. 7 is an int, 7U is an unsigned int, 7L is a long, 7.0 is a double, and 7.0f is a float. The character constant 'B' can initialize a char. The string literal "B" is different and cannot replace 'B' in that declaration.

For the program below, use %d for int, %u for unsigned int, %c for a character and %f for a floating argument, which is promoted when passed to printf. %.2f displays two digits after the decimal point.

Input formats need extra care:

c
int age;
double cgpa;

if (scanf("%d %lf", &age, &cgpa) == 2) {
    printf("Age %d, CGPA %.2f\n", age, cgpa);
}

For input 21 8.35, this prints Age 21, CGPA 8.35. scanf needs addresses. Its %lf expects a double *, while %f expects a float *.

Fully Worked C Program: Calculate a Marks Average from Typed Values

First check the arithmetic. 563 / 7 is 80 with remainder 3, because 7 × 80 = 560 and 563 - 560 = 3. Converting total_marks before division gives 563.0 / 7.0, approximately 80.428571. Printing that value with %.2f gives 80.43.

Save this complete program as marks.c:

c
#include <stdio.h>

int main(void) {
    const int subject_count = 7;
    int total_marks = 563;
    double average = (double) total_marks / subject_count;
    char section = 'B';
    unsigned int attempts = 3U;

    printf("Subjects: %d\n", subject_count);
    printf("Total marks: %d\n", total_marks);
    printf("Average: %.2f\n", average);
    printf("Section: %c\n", section);
    printf("Attempts: %u\n", attempts);
    return 0;
}

Here %d matches each int, %.2f formats the double, %c matches the character and %u matches the unsigned int. Compile and run it:

bash
gcc -std=c17 -Wall -Wextra -pedantic marks.c -o marks
./marks

The exact output is:

Code
Subjects: 7
Total marks: 563
Average: 80.43
Section: B
Attempts: 3

Warnings help reveal suspicious code, but an absence of warnings does not prove that every result is correct.

Integer Division, Implicit Conversion and Explicit Casts

Compare these assignments:

c
double wrong_average = total_marks / subject_count;
double average = (double) total_marks / subject_count;

In the first line, both operands are int, so integer division happens first. 563 / 7 becomes 80, and only then is that result stored as 80.0. A double destination on the left does not go back and change the division on the right.

In the second line, the cast changes the left operand to 563.0 before division. The other operand is then converted to 7.0, so floating-point division produces approximately 80.428571. The useful general rule is: evaluate operands using their converted expression types, then convert the result for assignment.

Conversion to an integer discards the fractional part toward zero. Therefore (int)19.75 becomes 19, while (int)-19.75 becomes -19. A cast records an intentional conversion, but it cannot make an out-of-range value safe.

Two conversion paths for 563 divided by 7: integer division stored as 80.0 versus a double cast that prints 80.43.

Common Variable and Data Type Errors, with the Repair Beside Each

Mistake

Consequence and repair

Read int count; before assigning it

An uninitialized automatic object has an indeterminate value, and reading it can be undefined behaviour. Initialize before reading.

Use the wrong printf or scanf format

The variadic call is invalid. Match the conversion specifier and, for scanf, the pointer type.

Assign 19.75 to an int

The fraction is discarded. Keep a floating type, or cast only when truncation is deliberate.

Assume one fixed int size

The code becomes non-portable. Measure with sizeof on the target implementation.

Signed integer overflow is undefined behaviour, so signed wraparound is not a C rule. Unsigned arithmetic is modulo its range. If unsigned int stock = 0U; is decremented, the result is UINT_MAX. Read that value from the implementation instead of guessing it.

Mixed signed and unsigned operands are another trap. With int debt = -1; unsigned int credit = 1U;, debt < credit can surprise you because the usual arithmetic conversions turn the signed value into an unsigned value. Choose compatible types and validate ranges before conversion.

How Tests and Interviews Check C Variables and Data Types

Common learning checks ask you to identify a declaration's parts, choose a type and format, predict integer versus floating division, trace a cast, spot an uninitialized read or reject a machine-specific size assumption.

Try four rapid traces:

  • For int a = 17, b = 5;, a / b is 3, while (double)a / b prints 3.40 with %.2f.

  • Input 12 7.25 with %d %lf stores 12 and 7.25.

  • (int)42.9 gives 42.

  • Decrementing unsigned int u = 0U gives UINT_MAX, not signed -1.

Now code two exercises. For int boxes = 9, items = 74;, derive quotient 8, remainder 2, floating result approximately 8.222222, and output 8.22 with %.2f. Then change the marks program to subject_count = 8 and total_marks = 647. The division is 647 / 8 = 80.875, so the displayed average is 80.88.

Once these traces are stable, Programming Languages provides neighbouring language tutorials. KnowledgeGate also has over 130 live practice questions covering Data Type Fundamentals and Intro & Data Types in C Programming.

Variables and Data Types in C: The Short Version and Next Step

Declare before use, initialize before reading, and let the operand types govern each expression. Cast before division when you need floating arithmetic, match every format specifier to its value or pointer, and measure sizes on the actual implementation.

Compile the marks program with warnings, run the size probe and solve both exercises from blank code. Take the C Language course as the next structured C step. Use Coding for Placements later when you want broader, multi-language practice.