Variables and Data Types

Variables are like labeled boxes — each box has a name and a type, and can only hold the right kind of item. Put the wrong thing in, and things go wrong.

What Is a Variable

A variable is a named memory location in your program used to store data. Think of it as a box:

Variable Declaration and Initialization

Declaring a Variable

Declaring a variable tells the compiler: "I need a box, here's its name and what type of things it holds."

C
int age;
float weight;
char blood_type;

After declaration, the variable's value is undefined (a garbage value) — it contains whatever random data was left in that memory location. Never use an uninitialized variable!

Initializing a Variable

Initialization means giving a variable an initial value at the same time you declare it:

C
int age = 20;
float weight = 65.5f;
char blood_type = 'A';
💡 Tip: Always initialize variables when you declare them. This is a good habit that helps you avoid many hard-to-track bugs caused by undefined values.

Declare First, Assign Later

You can also declare first and assign later:

C
int age;
age = 20;

This has the same effect, but the two-step approach is more spread out, making it easier to accidentally use the variable between declaration and assignment while it's still uninitialized.

Declaring Multiple Variables of the Same Type

C
int a = 1, b = 2, c = 3;
⚠️ Note: Declaring and initializing multiple variables on the same line hurts readability. If each variable has a meaningful initial value, write them on separate lines.

Variable Naming Rules

C has strict rules for variable names:

Must follow:

Should follow:

Name Valid? Notes
age Valid Short and meaningful
_count Valid Starts with underscore
student_name Valid snake_case style
2nd_place Invalid Starts with a digit
my-score Invalid Contains hyphen (interpreted as subtraction)
int Invalid Keyword
Age Valid but not recommended Capital first letter usually reserved for type names

Basic Data Types

A C data type determines how much memory a variable occupies, the range of values it can hold, and how the data is interpreted. Here are C99's basic data types:

Integer Types

Type Size (bytes) Typical Range Format Specifier
char 1 -128 ~ 127 %c or %d
unsigned char 1 0 ~ 255 %u
short 2 -32768 ~ 32767 %hd
unsigned short 2 0 ~ 65535 %hu
int 4 -2147483648 ~ 2147483647 %d
unsigned int 4 0 ~ 4294967295 %u
long 4 or 8 Platform-dependent %ld
unsigned long 4 or 8 Platform-dependent %lu
long long 8 -9223372036854775808 ~ 9223372036854775807 %lld
💡 Tip: For everyday programming, int is sufficient. Use long long when you need a larger range, and char for characters. short is rarely used on modern platforms because int is typically just as efficient.

⚠️ Note: The table above shows int as 4 bytes, which is the case on most modern platforms. However, the C standard only requires int to be at least 2 bytes. The actual size depends on the platform — use sizeof to confirm.

Floating-Point Types

Type Size (bytes) Significant Digits Range (absolute value) Format Specifier
float 4 6-7 1.2e-38 ~ 3.4e38 %f
double 8 15-16 2.2e-308 ~ 1.8e308 %lf
long double 8 or more 18+ Platform-dependent %Lf

Floating-point numbers have limited precision and cannot represent all decimals exactly. For example:

C
float f = 0.1f;
printf("%.20f\n", f);
TEXT
0.10000000149011611938

0.1 is an infinitely repeating binary fraction, so float can't store it precisely. This is an inherent characteristic of floating-point representation, not a bug.

🔥 Common Mistake: Use double by default when you need decimal numbers. It offers higher precision and is no slower than float on modern CPUs. Only prefer float on memory-constrained embedded systems.

The Character Type

The char type is essentially a 1-byte integer, typically used to store characters. Characters are stored in memory as ASCII codes:

C
char ch = 'A';
printf("%c\n", ch);
printf("%d\n", ch);
TEXT
A
65

The ASCII code for 'A' is 65. Using %c prints the character, while %d prints the integer value. This shows that characters and integers are interchangeable in C.

⚠️ Note: 'A' is a character (single quotes), while "A" is a string (double quotes, with a trailing \0). They are completely different — never mix them up.

The _Bool Type

C99 introduced the _Bool type, which can only store 0 and 1. Include <stdbool.h> to use bool, true, and false:

C
#include <stdbool.h>

bool is_valid = true;
bool is_empty = false;

The sizeof Operator

sizeof is a C keyword (not a function) that returns the number of bytes a data type or variable occupies:

Example

C
#include <stdio.h>

int main(void) {
    printf("char:   %zu bytes\n", sizeof(char));
    printf("short:  %zu bytes\n", sizeof(short));
    printf("int:    %zu bytes\n", sizeof(int));
    printf("long:   %zu bytes\n", sizeof(long));
    printf("long long: %zu bytes\n", sizeof(long long));
    printf("float:  %zu bytes\n", sizeof(float));
    printf("double: %zu bytes\n", sizeof(double));
    return 0;
}
▶ Try it Yourself
TEXT
char:   1 bytes
short:  2 bytes
int:    4 bytes
long:   4 bytes
long long: 8 bytes
float:  4 bytes
double: 8 bytes
💡 Tip: sizeof returns a size_t type, whose format specifier is %zu. If your compiler doesn't support %zu (some older versions), you can use %lu instead.

sizeof also works with variables:

C
int age = 20;
printf("%zu\n", sizeof(age));

Formatted Output in Detail

Integer Formatting

C
int n = 42;
printf("Decimal: %d\n", n);
printf("Octal: %o\n", n);
printf("Hex (lowercase): %x\n", n);
printf("Hex (uppercase): %X\n", n);
printf("Octal with prefix: %#o\n", n);
printf("Hex with prefix: %#x\n", n);
TEXT
Decimal: 42
Octal: 52
Hex (lowercase): 2a
Hex (uppercase): 2A
Octal with prefix: 052
Hex with prefix: 0x2a

Floating-Point Formatting

C
double pi = 3.141592653589793;
printf("Default: %f\n", pi);
printf("2 decimal places: %.2f\n", pi);
printf("8 decimal places: %.8f\n", pi);
printf("Scientific notation: %e\n", pi);
printf("Width 12.2f: [%12.2f]\n", pi);
TEXT
Default: 3.141593
2 decimal places: 3.14
8 decimal places: 3.14159265
Scientific notation: 3.141593e+00
Width 12.2f: [       3.14]

Type Value Ranges

The C standard library provides header files for querying the range of each type:

limits.h (Integer Types)

C
#include <limits.h>

printf("int min: %d\n", INT_MIN);
printf("int max: %d\n", INT_MAX);
printf("char max: %d\n", CHAR_MAX);

Common macros:

Macro Meaning
INT_MIN Minimum value of int
INT_MAX Maximum value of int
CHAR_MIN Minimum value of char
CHAR_MAX Maximum value of char
LONG_MAX Maximum value of long
LLONG_MAX Maximum value of long long

float.h (Floating-Point Types)

C
#include <float.h>

printf("float significant digits: %d\n", FLT_DIG);
printf("double significant digits: %d\n", DBL_DIG);
printf("float max value: %e\n", FLT_MAX);

Example

Example

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

int main(void) {
    char ch = 'Z';
    int num = 100;
    float f = 3.14f;
    double d = 2.718281828;

    printf("char '%c' = ASCII %d, size = %zu\n", ch, ch, sizeof(ch));
    printf("int %d, size = %zu, range = [%d, %d]\n", num, sizeof(num), INT_MIN, INT_MAX);
    printf("float %.6f, size = %zu, digits = %d\n", f, sizeof(f), FLT_DIG);
    printf("double %.9f, size = %zu, digits = %d\n", d, sizeof(d), DBL_DIG);

    return 0;
}
▶ Try it Yourself
TEXT
char 'Z' = ASCII 90, size = 1
int 100, size = 4, range = [-2147483648, 2147483647]
float 3.140000, size = 4, digits = 6
double 2.718281828, size = 8, digits = 15

Example

C
#include <stdio.h>

int main(void) {
    char lower = 'a';
    char upper = lower - 32;

    printf("Lowercase: %c (ASCII %d)\n", lower, lower);
    printf("Uppercase: %c (ASCII %d)\n", upper, upper);

    printf("\nDigit characters:\n");
    char digit = '0';
    printf("Character '%c' ASCII code = %d\n", digit, digit);
    printf("Character '%c' numeric value = %d\n", digit, digit - '0');

    return 0;
}
▶ Try it Yourself
TEXT
Lowercase: a (ASCII 97)
Uppercase: A (ASCII 65)

Digit characters:
Character '0' ASCII code = 48
Character '0' numeric value = 0
💡 Tip: Uppercase and lowercase ASCII codes differ by 32. Subtract 32 from a lowercase letter to get its uppercase equivalent, and add 32 to go the other way. Subtracting '0' from a digit character gives its numeric value — this is the basis for converting characters to numbers.

❓ FAQ

Q What's the difference between int and long long? When should I use long long?
A int is typically 4 bytes with a maximum around 2.1 billion; long long is 8 bytes with a maximum around 9.2 quintillion. Use long long when int's range isn't enough (e.g. computing factorials, large-number arithmetic). For everyday programming, int is sufficient — don't default to long long, as it wastes memory and may be slower on some platforms.
Q Should I choose float or double?
A Default to double. double has 15-16 significant digits versus float's 6-7 — a huge precision difference. On modern CPUs, double arithmetic is just as fast as float. Only prefer float on memory-constrained embedded devices.
Q Is char signed or unsigned?
A It depends on the compiler and platform. The C standard doesn't specify whether char is signed — compilers decide. If you need a guaranteed sign, use signed char or unsigned char explicitly. For ASCII characters (0-127), it doesn't matter. For values above 127, you must be explicit.
Q Why shouldn't I use uninitialized variables?
A Uninitialized local variables are stored on the stack and contain whatever random data was left in memory (garbage values). Using them leads to undefined behavior — the program might work sometimes and crash other times, with different results each run. These bugs are extremely hard to track down, so always initialize variables at declaration.

📖 Summary

📝 Exercises

  1. Write a program that uses sizeof to print the byte sizes of all integer and floating-point types on your computer. Compare with a classmate's results to see if they match.
  2. Write a program that prints the ASCII codes for letters 'a' through 'z', five per line, using %-5d for alignment.
  3. Calculate and print the result of INT_MAX + 1 (integer overflow). Compare the output with INT_MIN and think about why this happens.
100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏