C printf Specifiers for Pointers and size_t

In the C programming language, outputting memory addresses and type sizes requires specific format specifiers to ensure portability and prevent undefined behavior. This guide details the correct specifiers used in the printf family of functions to display pointer addresses using %p and system size types—such as size_t and ptrdiff_t—using the %zu and %td length modifiers introduced in the C99 standard.

Printing Pointer Addresses

The standard specifier for printing memory addresses of pointers is %p.

According to the ISO C standard, %p expects an argument of type void *. If you are passing any other pointer type (such as an int * or char *), it should be explicitly cast to (void *) to guarantee standard-compliant and portable behavior across different architectures.

#include <stdio.h>

int main(void) {
    int value = 42;
    int *ptr = &value;

    printf("Pointer address: %p\n", (void *)ptr);
    return 0;
}

The output format of %p is implementation-defined, but most modern compilers format it as a hexadecimal value (e.g., 0x7ffee4b29abc).

Printing Size Types (size_t)

The size_t type is an unsigned integer used to represent the sizes of objects in memory, such as the value returned by the sizeof operator.

To print values of type size_t, use the specifier %zu:

  • z is the length modifier indicating that the following conversion specifier applies to a size_t argument.
  • u indicates that the value should be printed as an unsigned decimal integer.
#include <stdio.h>

int main(void) {
    size_t array_size = 100;
    
    printf("Array size: %zu\n", array_size);
    printf("Size of int: %zu bytes\n", sizeof(int));
    return 0;
}

Printing Signed Size Types and Pointer Differences

  • ssize_t (Signed Size): If using POSIX systems that utilize ssize_t for values that can represent a size or a negative error code (like read() system calls), use %zd.
  • ptrdiff_t (Pointer Difference): When subtracting one pointer from another within the same array, the result is of type ptrdiff_t. The format specifier for signed pointer differences is %td.
#include <stdio.h>
#include <stddef.h>

int main(void) {
    int numbers[] = {10, 20, 30, 40};
    ptrdiff_t diff = &numbers[3] - &numbers[0];

    printf("Element distance: %td\n", diff);
    return 0;
}