Register

C for Beginners

0 of 24 notes read 0%

Reading progress is saved to your INFIRALS account. Sign in to keep this note marked as read.

Variables, types, and values

Starting out12 min readLesson 3 of 5

3.1 A variable is a named box

A variable is a name for a storage location that holds a value of one type. C is statically typed: the type is fixed when you declare the variable, and it decides how many bytes the location uses and how those bytes are read.

int count; reserves space and leaves the value undetermined. int count = 0; also stores a zero.

The value of an uninitialised local variable cannot be predicted. The location holds whatever bytes were already there, and reading it is undefined behaviour: the C standard gives no rule for the result, so the compiler may do anything. Initialise a local variable at the point where you declare it.

3.2 The basic types

  • int holds a whole number. Most desktop compilers give it 4 bytes, with a range of about 2.1 billion in each direction.
  • char holds one byte, most often a character code such as 'A'.
  • float holds a single-precision real number.
  • double holds a double-precision real number and is the usual choice for decimals.
  • unsigned int holds only non-negative values and can store about twice the largest int.
  • bool, from <stdbool.h>, holds true or false. In C23 it is a keyword and the header is optional.

Use double for money in practice programs. float keeps about seven significant digits, and double keeps about fifteen, which is enough for prices printed with two decimals.

c
#include <stdio.h>

int main(void)
{
    int small = 42;
    double price = 19.99;
    char grade = 'A';

    printf("int: %d, %zu bytes\n", small, sizeof small);
    printf("double: %.2f, %zu bytes\n", price, sizeof price);
    printf("char: %c, %zu byte\n", grade, sizeof grade);
    return 0;
}

Output

int: 42, 4 bytes
double: 19.99, 8 bytes
char: A, 1 byte

3.3 Declaring and initialising

A name may contain letters, digits, and underscores, and it cannot start with a digit. Names are case sensitive, so Total and total are different variables. Keywords such as int, return, and while are reserved and cannot be used as names.

C99 and later allow a declaration in the middle of a block, close to the first use. C89 required every declaration at the top of the block, and older code still follows that layout.

const int limit = 100; marks a value that cannot be changed after initialisation. A constant declared this way behaves like a variable in every other respect; the compiler refuses only the assignment that would modify it.

c
#include <stdio.h>

int main(void)
{
    const int limit = 5;
    int a = 2, b = 3;
    int total = a + b;

    printf("a = %d, b = %d\n", a, b);
    printf("total = %d, limit = %d\n", total, limit);
    printf("a + b + limit = %d\n", total + limit);
    return 0;
}

Output

a = 2, b = 3
total = 5, limit = 5
a + b + limit = 10

3.4 Matching types to format specifiers

Each type needs a matching conversion specifier. printf does not convert an argument to the type named in the format string; it reads the argument according to the specifier.

  • int: %d
  • unsigned int: %u
  • long: %ld
  • long long: %lld
  • double: %f
  • char: %c
  • size_t: %zu

scanf needs the address of the variable and a matching specifier: scanf("%d", &count);. The & is the address-of operator, which the pointers lesson explains. For now, remember that printf receives values while scanf receives addresses.

A wrong specifier is not always caught at compile time. Pay attention to the warning format '%d' expects argument of type 'int', which GCC and Clang print when the types are obviously wrong.

c
#include <stdio.h>

int main(void)
{
    int age = 0;

    printf("Enter your age: ");
    scanf("%d", &age);            /* sample input: 14 */
    printf("Next year you will be %d.\n", age + 1);
    return 0;
}

Output

Enter your age: Next year you will be 15.

3.5 Integer division and mixed arithmetic

Division depends on the types of its operands. 7 / 2 with two int values gives 3, because C discards the fraction. 7.0 / 2 gives 3.5, because the int operand is converted to double first.

  • when both operands are integers, / truncates toward zero
  • % gives the remainder and accepts integers only
  • mixing int and double promotes the int to double
  • assigning a double to an int truncates the fraction
  • a cast such as (double) total converts one operand before the operation happens

-Wconversion reports some accidental conversions. It is noisy on large programs and useful on small exercises.

c
#include <stdio.h>

int main(void)
{
    int total = 7;
    int parts = 2;

    printf("Integer division: %d\n", total / parts);
    printf("Remainder: %d\n", total % parts);
    printf("Real division: %.1f\n", (double) total / parts);
    return 0;
}

Output

Integer division: 3
Remainder: 1
Real division: 3.5

3.6 Characters and small integers

char stores a character code. On an ASCII system, 'A' is 65, 'B' is 66, and 'a' is 97. Printing a char with %c shows the character, and printing it with %d shows the code.

'A' is a character constant. "A" is a string literal with two bytes: the character 'A' and the terminating '\0'. Mixing the two up produces a warning from most compilers and strange output from the program.

c
#include <stdio.h>

int main(void)
{
    char letter = 'C';

    printf("letter: %c\n", letter);
    printf("code: %d\n", letter);
    printf("next: %c\n", letter + 1);
    return 0;
}

Output

letter: C
code: 67
next: D

Interview questions

3 questions from this note. Open one to see the answer; no account needed.

  • 01Why should a local variable be initialised?

    An uninitialised local variable holds whatever bytes were in that memory. Reading it is undefined behaviour, so the value has no guaranteed meaning.

  • 02What is the difference between `float` and `double`?

    `float` usually uses 32 bits and keeps about seven significant digits. `double` usually uses 64 bits and keeps about fifteen. Use `double` for calculations unless memory is tight.

  • 03Why does `7 / 2` produce 3?

    Both operands are `int`, so C performs integer division and discards the fraction. Write `7.0 / 2` or cast one operand to `double` to get `3.5`.