When used with arithmetic operators, all small integer types (bool, char, short) are subjected to integer promotions before any arithmetic is perfomed on them. In the a + 1 expression your a is promoted to int meaning that this expression is actually interpreted as (int) a + 1. The range of char plays no role here. All calculations are performed in the domain of int and the result has int type. 127 + 1 is 128, which is what you see printed.
Your ++i is defined as i = i + 1. For the same reasons the right-hand side is calculated as (int) i + 1, meaning that in this case the addition is performed in the domain of int as well. Later the result is converted back to char and stored back into i. The addition itself does not overflow and produces 128, but the subsequent conversion back to char "overflows", which produces implementation-defined behavior. In your case that implementation-defined behavior produced the value of -128 as char result.