Different isn't the same. Try this:
#include <cstdio>
#include <iostream>
int main() {
    int i = '6';
    char *ii = reinterpret_cast<char*>(&i);
    std::printf("%c\n", *ii);
    std::printf("%d\n", *ii);
    std::cout << *ii << '\n';
    std::cout << (int)*ii << '\n';
}
Initializing i to '6' is just a clarification.
In the calls to printf, the char value that *ii points to is promoted to int in the function call. Types smaller than int get promoted when they're arguments to the variable part of a function that takes a variable parameter list (such as printf).
The first printf statement prints the value of *ii as a character value; you'll get "6". The second prints it as an integer value; you'll get whatever value represents the character '6' (in ASCII that's 54, which is probably what you'll see).
The first insertion into std::cout inserts the char value; stream inserters are overloaded for integral types, so you get the inserter that takes an argument of type char, and it displays the character that the value represents, just like the first printf call.
The second insertion into std::cout inserts the integer value of *ii, just like the second call to printf.