C言語の真偽と文字列の比較について解らないので教えてください。

1:真偽について
真偽について入門書には「偽が0、真が0以外」と有るのですが、if(strcmp(str1, str2) == 0)で真と偽が逆になってるような気がするのですがこの0は真偽の0とは別の意味ですか?

2:文字列の比較について
文字列を比較する場合はstrcmp関数を使うとあるのですが、文字列の変数同士は確かに比較で誤った結果になるのですがポインター変数や文字列そのものを比較する時は誤ってないようにも見えます。
if(str3 == "ABC")はうまく動作してるようですが、実はそう見えてるだけでこれは間違った比較方法なのでしょうか?

int main(void) {
    char str1[10] = "ABC";
    char str2[10] = "ABC";
    char *str3 = "ABC";

    if (strcmp(str1, str2) == 0) {
        puts("真");
    } else {
        puts("偽");
    }

    if (str3 == "ABC") {
        puts("str3 = 真");
    } else {
        puts("str3 = 偽");
    }
    return 0;
}