Do not set $? to non-zero on Control+C

I don't think there's any way to turn it off.

First thought is to have preexec set a variable that indicates a command was run. If you pressed Ctrl+C at the prompt, it wouldn't get set.

precmd() {
    exit_status=$?
    if ! $ran_something; then
        exit_status=0
    fi
    ran_something=false
}
preexec() {
    ran_something=true
}
show_non_zero_exit_status() {
    case $exit_status in
    0)
        :;;
    *)
        echo $exit_status;;
    esac
}
PS1='$(show_non_zero_exit_status)$ '

But there's another similar problem: if you suspend a command, you'll get exit status 20 (zsh < 5.0.7) or 148 (bash and zsh >= 5.0.7).

To get around that, you can add 20|148 to the case statement above, i.e.

show_non_zero_exit_status() {
    case $exit_status in
    0|20|148)
        :;;
    *)
        echo $exit_status;;
    esac
}

If you're using zsh, make sure you have setopt promptsubst in your .zshrc.

If you're using bash, add:

PROMPT_COMMAND=precmd
trap preexec DEBUG

but really you should use the more complicated DEBUG trap mentioned in https://superuser.com/a/175802/15334

Another possibility is that setopt printexitvalue is close enough to what you want.